HTTP status for functional redirect

2019-05-04 15:49发布

问题:

Right now we've got web pages that show UI elements, and web pages that just process form submissions, and then redirect back to the UI pages. They do this using PHP's header() function:

header("Location: /other_page.php");

This causes a 302 Found response to be sent; according to the HTTP 1.1 spec, 302 is for cases where "The requested resource resides temporarily under a different URI." [HTTP 1.1 spec]

Functionally, this is fine, but it doens't seem like this is the proper status code for what we're doing. It looks like 303 ("See Other") is the appropriate status here, so I'm wondering if there's any reason not to use it. We'd have to be more explicit in our use of header(), since we'd have to specify that status line rather than just a Location: field. Thoughts?

回答1:

You can use either, but the proper statuscode to use for redirect-after-post is 303.

The confusion has a historical explanation. Originally, 302 specified that the browser mustn't change the method of the redirected request. This makes it unfit for redirect-after-post, where you want the browser to issue a GET request. However, all browsers seems to misinterpret the specs and always issue a GET request. In order to clear up the ambiguity HTTP/1.1 specified two new codes: 303 and 307. 303 essentially specifies the de-facto interpretation of 302, while 307 specifies the original specification of 302. So in practice 302 and 303 are interchangeable, and in theory 302 and 307 are.

If you really care about compatibility, 302 is a safer bet than 303, since HTTP/1.0 agents may not understand 303, but all modern browsers speak HTTP/1.1, so it isn't a real issue. I would recommend using 303, since that's the most correct thing to do.

On a side-note; The Location field should be a full URL. In practice it doesn't matter - browsers are forgiving - but if you care about the specs, that's the proper thing to do.



回答2:

I've never used it myself... as it says in your link:

Note: Many pre-HTTP/1.1 user agents do not understand the 303 status. When interoperability with such clients is a concern, the 302 status code may be used instead, since most user agents react to a 302 response as described here for 303.

This seems a good enough reason to me to stick with 302.

FYI header() takes extra parameters in which you can set the status code:

header('Location: /foo.php', true, 303);



回答3:

To expand on RoBorg's answer, many browsers do not understand more than a handful of the many, many HTTP response codes.

A side note: it you are at all concerned about search engine placement, 302s can (supposedly) cause problems.