表当一个普通的表单提交,或一个Ajax请求访问,使浏览器重定向 - 这可能吗?表单、这可、一个普通、重定向

2023-09-10 13:33:31 作者:密码里都藏有秘密

我有一个形式的网页。当用户提交表单,我希望服务器使浏览器从表单操作重定向到另一个页面。现在,我通过使用PHP的头这样函数来发送一个302状态code。它工作正常。

I have a web page with a form. When the user submits the form, I want the server to make the browser redirect to a different page from the form action. Right now, I am doing this by using PHP's header function to send a 302 status code. It works fine.

我试图使在服务器上的页面浏览器重定向以同样的方式,不管它是否被正常提交(不使用Javascript)或通过Ajax。我试图通过设置窗口位置的任何URL在Location头做到这一点。我使用jQuery的,做这样的呼吁:

I am trying to make the page on the server redirect the browser in the same way, regardless of whether it was submitted normally (without Javascript) or via Ajax. I tried to do this by setting the window location to whatever URL is in the Location header. I am using jQuery, and doing a call like this:

$.ajax({
    url: this.action,
    type: "POST",
    data: getFormData(this),
    complete: function(request) {
        window.location.assign(request.getResponseHeader("Location"));
    }
});

然而,没有工作。考虑这件事后,我意识到,这是不是很奇怪。在一个Ajax请求,浏览器应该透明地处理不断变化的readyState的前重定向响应,如302 codeS。当完整的功能运行时,它正在寻找的最终目的地Location头并没有找到它。

However, that didn't work. After thinking about it, I realized that this is not very surprising. In an Ajax request, the browser is supposed to transparently handle redirect responses such as 302 codes before changing the readyState. When the complete function runs, it is looking for the Location header in the final destination and not finding it.

作为一个实验,我又试图发送一个200状态code与Location头。我尝试了Ajax请求,它能正常工作。然而,当我做了非Ajax提交,但没有奏效。浏览器去了表单操作页面,并在那里呆了,好像是忽略了Location头。

As an experiment, I then tried sending a 200 status code with a Location header. I tried the Ajax request and it worked fine. However, when I did the non-Ajax submit, it didn't work. The browser went to the form action page and stayed there, like it was ignoring the Location header.

有没有什么办法让同一个页面重定向在这两种情况下,如果没有服务器不必知道或关心的请求是否是一个Ajax请求?

Is there any way to make the same page redirect in both cases, without the server having to know or care whether the request is an Ajax request?

在这种情况下的问题,我想在不同的浏览器(IE8,IE7,IE6,火狐3.5,Chrome浏览器),每次类似的结果的形式。另外,我做一个POST请求,以避免碰撞到IE的2083个字符的URL长度的限制。

In case this matters, I tried the form in various browsers (IE8, IE7, IE6, Firefox 3.5, Chrome) with similar results each time. Also, I am doing a post request to avoid bumping into IE's 2083-character URL length limit.

推荐答案

HTTP 302响应由 XmlHtt prequest 实施默默的消耗(如jQuery的 AJAX 函数)。这是一个特点。

HTTP 302 response are consumed silently by XmlHttpRequest implementations (e.g. jQuery's ajax function). It's a feature.

我已经在过去解决这个问题的方法是,以检测XmlHtt prequests并出具的 内容 - 位置头(而不是位置头)。这样做的最大的跨库的方法是检查是否X-要求,以在你的服务器端code HTTP标头(jQuery的,原型,等等MooTools的设置此):

The way I've solved this in the past is to detect for XmlHttpRequests and issue a "Content-Location" header (rather than a "Location" header). The most cross-library way of doing this is to check for the "X-Requested-With" http header in your server-side code (jQuery, Prototype, Mootools among others set this):

if (@$_SERVER['HTTP_X_REQUESTED_WITH']  == 'XMLHttpRequest') {
    header('Content-Location: ' . $redirect_url);
} else {
    header('Location: ' . $redirect_url);
}

您还需要特殊情况下,你的客户端code:

You still need to special-case your client-side code:

$.ajax({
    // ...
    complete: function(xhr) {
        var redirect_url = xhr.getResponseHeader("Content-Location");
        if (redirect_url) {
            window.location = redirect_url;
        }
    }
})