As per the HTTP specification:
If a resource has been created on the
origin server, the response SHOULD
be 201 (Created) and contain an entity
which describes the status of the
request and refers to the new
resource, and a Location header
(see section 14.30).
Does this mean that POST request should always send redirect URI in Location header with no response body?
It is perfectly acceptable to specify a response body and use the Location header at the same time. When using the Location header with a 201 response, you're not redirecting the client, you're just telling it where it can find the resource in future.
Redirects only apply to 3xx responses.
The W3C docs for this explain further, though the text is actually quite ambiguous:
The Location response-header field is used to redirect the recipient to a location other than the Request-URI for completion of the request or identification of a new resource. For 201 (Created) responses, the Location is that of the new resource which was created by the request. For 3xx responses, the location SHOULD indicate the server's preferred URI for automatic redirection to the resource.
I read that as saying "...redirect... or... identif[y]... new resource", but it's not exactly a plain English sentence.
Based on paragraph 9.5 of the HTTP 1.1 specification, which is the reference for questions like that, here is my understanding:
Yes you can, and the specification is clear about what you can do and how to do it:
The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.
If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).
Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.
Related
RFC 2616 defines the Location header as:
The Location response-header field is used to redirect the recipient to a location other than the Request-URI for completion of the request or identification of a new resource
...
For 3xx responses, the location SHOULD indicate the server's preferred URI for automatic redirection to the resource.
AFAIK, for 3xx Redirection codes, the Location header is:
300 Multiple Choices : optional
301 Moved Permanently : required
302 Found : required
303 See Other : required
304 Not Modified : irrelevant
305 Use Proxy : irrelevant (?)
306 Switch Proxy : irrelevant (?)
307 Temporary Redirect : required
308 Permanent Redirect : required
But that's just from personal experience. Is there a standard that defines which HTTP codes require the Location header to be sent?
That is, for which 3xx codes should an HTTP client throw an exception when received without a corresponding Location header?
This question has been asked back in the days when RFC 2616 has still been the authority, so it looked like a fun research project now that RFCs 7230 to 7235 are in place. So, let's see what we've got here.
The Location header is now defined in RFC 7231, section 7.1.2:
The "Location" header field is used in some responses to refer to a specific resource in relation to the response. The type of relationship is defined by the combination of request method and status code semantics.
[…]
For 201 (Created) responses, the Location value refers to the primary resource created by the request. For 3xx (Redirection) responses, the Location value refers to the preferred target resource for automatically redirecting the request.
The section does not confine this header solely to the 3xx-range of status codes. In fact, the only status codes explicitly being mentioned are 201 (Created) and 303 (See Other). No word about this header being actually required by any status code, though.
The purpose of the 3xx-range of codes is now described by RFC 7231, section 6.4:
The 3xx (Redirection) class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. If a Location header field is provided, the user agent MAY automatically redirect its request to the URI referenced by the Location field value, even if the specific status code is not understood.
The wording suggests that neither the presence nor automatically redirecting to its content is mandatory.
At the time of this writing, the IANA HTTP Status Code Registry is listing the codes 300 through 308 as registered. With one (305) being obsoleted and one being reserved (306), this is leaving seven active codes:
300: Multiple Choices – RFC 7231, section 6.4.1
The 300 code is to be returned if the server is aware of multiple representations of a resource. As of RFC 7231, there is no longer a recommended way to communicate a list of possible representations, though the Link header via RFC 5988 is being mentioned. Regarding the Location header, the RFC has this to say:
If the server has a preferred choice, the server SHOULD generate a Location header field containing a preferred choice's URI reference. The user agent MAY use the Location field value for automatic redirection.
Meaning the Location header is only to be used if the server has a preferred representation. If there is none, the server simply doesn't have such a preference.
It bears mentioning that the Location header by itself is unfit to list all possible representations as it is by its grammar a single-value field that cannot contain a list. Hence, the meaning of
Location: //example.com/a
Location: //example.com/b
is undefined.
301: Moved Permanently – RFC 7231, section 6.4.2
This response code is to let the client know there is an entirely new location for the requested resource: subsequent requests are to be directed at the location specified in the Location header.
The server SHOULD generate a Location header field in the response containing a preferred URI reference for the new permanent URI. The user agent MAY use the Location field value for automatic redirection.
Again, the presence of the Location header is no absolute requirement. The absence of this header would have questionable practicability. The semantics were akin - but not equal - to the 410 (Gone) response: "This resource is has permanently moved to a new, yet unknown location."
302: Found – RFC 7231, section 6.4.3
Originally this is has been specified as "Temporary Redirect" and got renamed in later specs. In contrast to 301 this one cannot (or should not) be cached or used to permanently rewrite URLs. The relevant part of the spec reads:
The server SHOULD generate a Location header field in the response containing a URI reference for the different URI. The user agent MAY use the Location field value for automatic redirection.
I believe the semantics of a missing Location header were pretty much the same as with 301: "This resource is has temporarily moved to a new, yet unknown location."
303: See Other – RFC 7231, section 6.4.4
303 is supposed to be returned in response to a POST request but is applicable to any method. In general, it is meant to let the client know there were a more appropriate representation at a substitute URL or the requested resource cannot be transmitted via HTTP.
In the context of this question, this is a bit of a headscratcher. RFC 2616, section 10.3.4 states:
The different URI SHOULD be given by the Location field in the response.
The relevant section of the newer RFC 7231 seems to simply presume the Location header being present:
the server is redirecting the user agent to a different resource, as indicated by a URI in the Location header field
There is nothing in the errata to clarify this, so I am inclined to assume the position of RFC 2616. The semantics of an absent Location header do differ depending on request method:
For POST this would be the same as 201 (Created) or 202 (Accepted)
For any other method, this were identical to 404 (Not Found)
304: Not Modified – RFC 7232, section 4.1
This response is in a way special as it stresses out on the "[indication] that further action needs to be taken by the user agent in order to fulfill the request." It should be understood as a redirect not to a new URI but to a local cache. There is no mention of the Location header in the relevant parts of RFC 7232 at all. In fact, this would make little sense as to my understanding the semantics were something like "the requested presentation of this entity has remained unchainged and you will find it in your local cache at …" That were a great breach of separation of concerns but is not to say Location were not allowed at this place. Still, Content-Location or a Link header with a rel=self part were more appropriate. Former one is receiving explicit mentioning:
The server generating a 304 response MUST generate any of the following header fields that would have been sent in a 200 (OK) response to the same request: Cache-Control, Content-Location, Date, ETag, Expires, and Vary.
305: Use Proxy – RFC 2616, section 10.3.6; RFC 7231, section 6.4.5
This status code has been deprecated as of RFC 7231 due to security concerns (cf Appendix B). Its definition in RFC 2616 reads:
The requested resource MUST be accessed through the proxy given by the Location field.
This implies the presence of a Location header, yet it does not explicitly require it. Omitting this header would have the semantic meaning of "this resource can only be accessed through some proxy."
306: Switch Proxy – draft-cohen-http-305-306-responses-00
Ths code has been introduced as a draft after RFC 2068 has been finalized and already got obsoleted by RFC 2616. To my knowledge, this draft has never reached the status of a recommendation, so this is purely for completeness. The rationale of this draft is to supply proxies with a mechanism to direct clients (temporarily) to other proxies for subsequent requests.
Part of this draft is the introduction of the Set-Proxy header which is to be used in place of the Location header per section 2.2:
In the original HTTP/1.1 spec, the 'Location' header was used to indicate the proxy setting. Its use is DEPRECATED by the 'Set-proxy' header in the context of a 305 response. All new implementations MUST send the Set-proxy header. Implementations MAY send the 'Location' header so as to allow backward compatibility.
Set-Proxy is then required in context of 306 while the Location header is purely optional. As the required Set-Proxy mechanism is meant to replace Location, the absence of latter header introduces no semantic changes.
307: Temporary Redirect – RFC 7231, section 6.4.7
307 got introduced as a result of a semantic change of 302 in HTTP/1.1: While redirects via 302 can change request methods, the redirected request must have the same request method as the original request.
The relevant part of the spec reads:
The server SHOULD generate a Location header field in the response containing a URI reference for the different URI. The user agent MAY use the Location field value for automatic redirection.
Again, Location seems to be optional. For semantic changes due to an absent header, see 302.
308: Permanent Redirect – RFC 7538
Like 307, redirects via 308 are to keep their original request method. One could say 308 were to 301 as 307 is to 302.
From section 3 of the spec:
The server SHOULD generate a Location header field in the response containing a preferred URI reference for the new permanent URI.
So, in summary we have got this situation:
Implied: 1 (305)
Optional: 1 (306)
No mention: 1 (304)
SHOULD: 6 (300; 301; 302; 303; 307; 308)
That "SHOULD" is to be read in the context of RFC 2119:
This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.
This is different from the absolute requirement of a "MUST" or "REQUIRED" (also in that RFC). So in a nutshell: There is no 3xx-class code in which the Location header is mandatory.
It should be noted, that the problem of a missing Location header is not a new one. From another answer:
301, 302, 303, and 307 provide a Location only if the next URL is known. Otherwise, the client/user has to decide what to do next
The specification does not mention what to do of the username:password in a URI returned by a Location such as:
Location: http://user:secret#w3.org/hidden/pages
Are we supposed to ignore such? It doesn't seem to make sense, but I was wondering what if it were to happen (i.e. server misconfiguration, strange idea from some administrator/programmer...)
14.30 Location
The Location response-header field is used to redirect the recipient
to a location other than the Request-URI for completion of the request
or identification of a new resource. For 201 (Created) responses, the
Location is that of the new resource which was created by the request.
For 3xx responses, the location SHOULD indicate the server's preferred
URI for automatic redirection to the resource. The field value
consists of a single absolute URI.
Location = "Location" ":" absoluteURI
An example is:
Location: http://www.w3.org/pub/WWW/People.html
Note: The Content-Location header field (section 14.14) differs
from Location in that the Content-Location identifies the original
location of the entity enclosed in the request. It is therefore
possible for a response to contain header fields for both Location
and Content-Location. Also see section 13.10 for cache
requirements of some methods.
RFC 2617 may have an answer. From section 3.3:
...For example
a server could be responsible for authenticating content that
actually sits on another server. It would achieve this by having the
first 401 response include a domain directive whose value includes a
URI on the second server, and an opaque directive whose value
contains the state information. The client will retry the request, at
which time the server might respond with a 301/302 redirection,
pointing to the URI on the second server. The client will follow the
redirection, and pass an Authorization header , including the
<opaque> data.
So I interpret that to mean that the Location header you get back from an HTTP redirect shouldn't actually contain the user:secret# parts at all, just the rest of the example URL you gave, and that you (the client) would be responsible for remembering the user/pass you sent in the Authorization header of the original request that was redirected, and to pass the same header again in the second request.
Update
Also, RFC 2396 section 3.2.2 has some words about using user/password in the URL:
Some URL schemes use the format "user:password" in the userinfo
field. This practice is NOT RECOMMENDED, because the passing of
authentication information in clear text (such as URI) has proven to
be a security risk in almost every case where it has been used.
I have a webpage that when landed on, will detect a user's physical location and then redirect them to the page most appropriate for the user.
What HTTP Status Code should be used for this redirect?
If there is a URI for the requester to utilize that would allow them to end up the same place without a redirect, then a 303 makes sense (as sjstrutt answered) as they should use the new location's URI. If not, a 302 makes sense to me because they should continue to use the Request-URI for future requests as you will then be redirecting them to a location lacking a URI they could otherwise request.
Heres what w3.org says about 302 status codes:
10.3.3 302 Found
The requested resource resides temporarily under a different URI.
Since the redirection might be altered on occasion, the client SHOULD
continue to use the Request-URI for future requests. This response is
only cacheable if indicated by a Cache-Control or Expires header
field.
The temporary URI SHOULD be given by the Location field in the
response. Unless the request method was HEAD, the entity of the
response SHOULD contain a short hypertext note with a hyperlink to the
new URI(s).
If the 302 status code is received in response to a request other than
GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
...
Emphasis mine.
As an aside: CodeIgniter's redirect() function defaults to 302, but mentions a 301 might be used for search engine redirects. Obviously that was their decision, but I figured I would throw that into the mix as it is a widely used web framework and I assume they have put some thought into it.
The appropriate response status code for a successful content negotiation is either 301, 302, or 307, depending on whether the redirect is permanent or only temporary.
But in any case, server-driven negotiation should always state which information the decision was based on. In HTTP, it’s the Vary response header field that specifies a list of request header fields that were used in this process.
Unfortunately, the client’s IP address (I guess you’re translating those into geolocation information) is not an option here. So a permanent redirect is not an option either, unless you indicate the response not to be cached, otherwise it could be cached by clients or intermediary proxies. So I would either use 302 or 307.
I believe that HTTP 303 is probably the most appropriate status code for a situation like this, though it may not be compatible with pre-HTTP 1.1 clients.
The HTTP 303 Status Code states (Note: I have bolded the parts that I feel are most important):
The response to the request can be found under a different URI and SHOULD be retrieved using a GET method on that resource. This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource. The new URI is not a substitute reference for the originally requested resource. The 303 response MUST NOT be cached, but the response to the second (redirected) request might be cacheable.
When a user is not logged in and tries to access a page that requires login, what is the correct HTTP status code for a redirect to the login page?
I am asking because none of the 3xx response codes set out by the W3C seem to fit the requirements:
10.3.1 300 Multiple Choices
The requested resource corresponds to
any one of a set of representations,
each with its own specific location,
and agent- driven negotiation
information (section 12) is being
provided so that the user (or user
agent) can select a preferred
representation and redirect its
request to that location.
Unless it was a HEAD request, the
response SHOULD include an entity
containing a list of resource
characteristics and location(s) from
which the user or user agent can
choose the one most appropriate. The
entity format is specified by the
media type given in the Content- Type
header field. Depending upon the
format and the capabilities of
the user agent, selection of the most
appropriate choice MAY be performed
automatically. However, this
specification does not define any
standard for such automatic selection.
If the server has a preferred choice
of representation, it SHOULD include
the specific URI for that
representation in the Location field;
user agents MAY use the Location field
value for automatic redirection. This
response is cacheable unless indicated
otherwise.
10.3.2 301 Moved Permanently
The requested resource has been
assigned a new permanent URI and any
future references to this resource
SHOULD use one of the returned URIs.
Clients with link editing capabilities
ought to automatically re-link
references to the Request-URI to one
or more of the new references returned
by the server, where possible. This
response is cacheable unless indicated
otherwise.
The new permanent URI SHOULD be given
by the Location field in the response.
Unless the request method was HEAD,
the entity of the response SHOULD
contain a short hypertext note with a
hyperlink to the new URI(s).
If the 301 status code is received in
response to a request other than GET
or HEAD, the user agent MUST NOT
automatically redirect the request
unless it can be confirmed by the
user, since this might change the
conditions under which the request was
issued.
Note: When automatically redirecting a POST request after
receiving a 301 status code, some existing HTTP/1.0 user agents
will erroneously change it into a GET request.
10.3.3 302 Found
The requested resource resides
temporarily under a different URI.
Since the redirection might be altered
on occasion, the client SHOULD
continue to use the Request-URI for
future requests. This response is only
cacheable if indicated by a
Cache-Control or Expires header field.
The temporary URI SHOULD be given by
the Location field in the response.
Unless the request method was HEAD,
the entity of the response SHOULD
contain a short hypertext note with a
hyperlink to the new URI(s).
If the 302 status code is received in
response to a request other than GET
or HEAD, the user agent MUST NOT
automatically redirect the request
unless it can be confirmed by the
user, since this might change the
conditions under which the request was
issued.
Note: RFC 1945 and RFC 2068 specify that the client is not allowed
to change the method on the redirected request. However, most
existing user agent implementations treat 302 as if it
were a 303
response, performing a GET on the Location field-value regardless
of the original request method. The status codes 303 and 307 have
been added for servers that wish to make unambiguously clear which
kind of reaction is expected of the client.
10.3.4 303 See Other
The response to the request can be
found under a different URI and SHOULD
be retrieved using a GET method on
that resource. This method exists
primarily to allow the output of a
POST-activated script to redirect the
user agent to a selected resource. The
new URI is not a substitute reference
for the originally requested resource.
The 303 response MUST NOT be cached,
but the response to the second
(redirected) request might be
cacheable.
The different URI SHOULD be given by
the Location field in the response.
Unless the request method was HEAD,
the entity of the response SHOULD
contain a short hypertext note with a
hyperlink to the new URI(s).
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.
10.3.5 304 Not Modified
If the client has performed a
conditional GET request and access is
allowed, but the document has not been
modified, the server SHOULD respond
with this status code. The 304
response MUST NOT contain a
message-body, and thus is always
terminated by the first empty line
after the header fields.
The response MUST include the
following header fields:
- Date, unless its omission is required by section 14.18.1 If a
clockless origin server obeys these
rules, and proxies and clients add
their own Date to any response
received without one (as already
specified by [RFC 2068], section
14.19), caches will operate correctly.
- ETag and/or Content-Location, if the header would have been sent
in a 200 response to the same request
- Expires, Cache-Control, and/or Vary, if the field-value might
differ from that sent in any previous response for the same
variant If the conditional GET used a strong cache validator (see
section 13.3.3), the response SHOULD
NOT include other entity-headers.
Otherwise (i.e., the conditional GET
used a weak validator), the response
MUST NOT include other entity-headers;
this prevents inconsistencies between
cached entity-bodies and updated
headers.
If a 304 response indicates an entity
not currently cached, then the cache
MUST disregard the response and repeat
the request without the conditional.
If a cache uses a received 304
response to update a cache entry, the
cache MUST update the entry to reflect
any new field values given in the
response.
10.3.6 305 Use Proxy
The requested resource MUST be
accessed through the proxy given by
the Location field. The Location field
gives the URI of the proxy. The
recipient is expected to repeat this
single request via the proxy. 305
responses MUST only be generated by
origin servers.
Note: RFC 2068 was not clear that 305 was intended to redirect a
single request, and to be generated by origin servers only. Not
observing these limitations has significant security consequences.
10.3.7 306 (Unused)
The 306 status code was used in a
previous version of the specification,
is no longer used, and the code is
reserved.
10.3.8 307 Temporary Redirect
The requested resource resides
temporarily under a different URI.
Since the redirection MAY be altered
on occasion, the client SHOULD
continue to use the Request-URI for
future requests. This response is only
cacheable if indicated by a
Cache-Control or Expires header field.
The temporary URI SHOULD be given by
the Location field in the response.
Unless the request method was HEAD,
the entity of the response SHOULD
contain a short hypertext note with a
hyperlink to the new URI(s) , since
many pre-HTTP/1.1 user agents do not
understand the 307 status. Therefore,
the note SHOULD contain the
information necessary for a user to
repeat the original request on the new
URI.
If the 307 status code is received in
response to a request other than GET
or HEAD, the user agent MUST NOT
automatically redirect the request
unless it can be confirmed by the
user, since this might change the
conditions under which the request was
issued.
I'm using 302 for now, until I find the correct answer.
Update & conclusion:
HTTP 302 is better since its known to have best compatibility with clients/browsers.
I'd say 303 see other 302 Found:
The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.
fits a login page most closely in my opinion. I initially considered 303 see other which would work just as well. After some thought, I'd say 302 Found is more fitting because the requested resource was found, there just is another page to go through before it can be accessed. The response doesn't get cached by default which is fine as well.
This is a misuse of HTTP redirection mechanism. If user is not authorized then your app must return 401 Unauthorized. In case that the user is authorized but does not have an access to the requested resource then 403 Forbidden must be returned.
You should do the redirect on client side, e.g. by javascript. status code for redirection because required authorization does not exist. Using 30x for this does not conform to HTTP.
How to Think About HTTP Status Codes by Mark Nottingham
401 Unauthorized triggers HTTP’s request authentication mechanism.
401 Unauthorized status code requires presence of WWW-Authenticate header that supports various authentication types:
WWW-Authenticate: <type> realm=<realm>
Bearer, OAuth, Basic, Digest, Cookie, etc
Hypertext Transfer Protocol (HTTP) Authentication Scheme
Registry
Cookie-based HTTP Authentication - DRAFT
I think the appropriate solution is the HTTP 401 (Not Authorized) header.
http://en.wikipedia.org/wiki/HTTP_codes#4xx_Client_Error
The purpose of this header is exactly this. But, instead of redirecting to a login page, the correct process would be something like:
User not logged try to access a login-restricted page.
system identifies user is not logged
system returns HTTP 401 header, AND display the login form in the same response (not a redirect).
This is a good practice, like providing a useful 404 page, with sitemap links, and a search form for example.
See you.
Lots of compelling and contradictory responses here! How to choose?
Finalists:
302 Found
Indicates that the resource requested has been
temporarily moved to the URL given by the Location header. A browser
redirects to this page but search engines don't update their links to
the resource.
The specification requires the method (and the body) not be
altered when the redirection is performed, but not all user-agents
conform. It
is therefore recommended to set the 302 code only as a response for
GET or HEAD methods and to use 307 Temporary Redirect instead, as the
method change is explicitly prohibited in that case.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302
Vague, possibly buggy, and maybe outdated, but could work, especially for GET requests.
307 Temporary Redirect
The resource requested has been temporarily moved to the URL given by
the Location header.
The only difference between 307 and 302 is that 307 guarantees that
the method and the body will not be changed when the redirected
request is made. With 302, some old clients were incorrectly changing
the method to GET: the behavior with non-GET methods and 302 is then
unpredictable on the Web, whereas the behavior with 307 is
predictable. For GET requests, their behavior is identical.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307
My original take was that if your application supports HTTP 1.1+, this would be the newer, clearer way to make a temporary redirect.
401 Unauthorized
indicates that the client request has not been completed because it
lacks valid authentication credentials for the requested resource.
This status code is sent with an HTTP WWW-Authenticate response header
that contains information on how the client can request for the
resource again after prompting the user for authentication
credentials.
This status code is similar to the 403 Forbidden status code, except
that in situations resulting in this status code, user authentication
can allow access to the resource.
I agree this was probably intended to be the correct response code to say, "Not until you sign in." But almost every webapp uses HTML forms with Cookies to sign-in and this HTTP code doesn't allow "Cookie" as an authentication scheme:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate
and
https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml
A few people have pointed out that someone drafted a "Cookie" scheme in 2009: WWW-Authenticate Cookie
https://datatracker.ietf.org/doc/html/draft-broyer-http-cookie-auth-00
Not sure why that didn't fly. Maybe because that's outside the realm of HTTP?
Without "Cookie" as an option, I think this is not suitable for HTML-and-Cookie based authentication.
Survey
In the absence of an undeniable single "correct" answer, I looked at what a few industry leaders were doing.
Google: 302 Redirect to Sign In Page
Request URL: https://mail.google.com/mail/u/0/?tab=cm Request Method:
GET Status Code: 302
Response:
content-type: text/html; charset=UTF-8 location:
https://accounts.google.com/ServiceLogin?service=mail&passive=1209600&osid=1&continue=https://mail.google.com/mail/u/0/?tab%3Dcm&followup=https://mail.google.com/mail/u/0/?tab%3Dcm&emr=1
Microsoft: 302 Redirect to Sign In page
Request URL:
https://outlook.live.com/mail/0/?authRedirect=true&state=0 Request
Method: GET Status Code: 302
Response: Location:
https://outlook.live.com/owa/0/?state=1&redirectTo=aHR0cHM6Ly9vdXRsb29rLmxpdmUuY29tL21haWwvMC8
Facebook: 302 Redirect to Sign In Page
Request URL: https://www.facebook.com/friends Request Method: GET
Status Code: 302
Response: location:
https://www.facebook.com/login.php?next=https%3A%2F%2Fwww.facebook.com%2Ffriends
Twitter: 200 with interstitial sign-in page
Request URL: https://twitter.com/messages/ Request Method: GET Status
Code: 200 (from service worker)
Me: 307: Temporary Redirect
I've used this for over a decade and never had a problem. Not suggesting that others adopt it, just saying it works as advertised as a 302 alternative in every major browser. I could be convinced to switch to using 302 as a result of researching this answer.
Conclusion
302 is the de-facto standard for redirects, unless you require a POST to be redirected to another POST, which I didn't try.
Really, I think a POST should either succeed or fail outright. POST causes a state change on the server (such as adding a product to inventory) and you really want to know if the change was processed and how many times. Redirecting would raise the question of whether your change was accepted or not before the redirect. Once you decide to NEVER redirect a POST, then 302 and 307 are equivalent. The "bugs" in 302 were in unrealistic use cases. Therefore, 307 should never have been created. Also 302 is more popular, so likely to be best supported.
The nice thing about using a single code for all temporary redirects is that you don't have to worry about the reason for the redirect.
200 with JavaScript throwing up an interstitial sign-in page is another option, probably more suited to single-page webapps. You asked for the page, you got the page, but you're going to be forced to sign in before you can see the contents.
Confused/inspired by a comment to my question Do search engines respect the HTTP header field “Content-Location”?, I’d like to know, what the exact purpose of the Content-Location header field in HTTP is and how it can be used.
In response to a GET request, Content-Location in HTTP can be used when a requested resource has multiple representations available, e.g. multiple languages. The selection of the resource returned will depend on the Accept headers in the original GET request.
Usually, the location specified in the Content-Location header is different to the location specified in the original request's URI.
In response to a PUT or POST request,
If the Content-Location URI is different than the requested URI, then the cache entry at the indicated URI is invalidated. (see https://www.rfc-editor.org/rfc/rfc7234#section-4.4 and https://www.rfc-editor.org/rfc/rfc2616#section-13.10)
If the Content-Location URI is the same as the requested URI, then that indicates to caches that the response to the PUT/POST request is the same as the response that would be received by a 200 response to a GET request at the same location and can thus be cached. (see https://www.rfc-editor.org/rfc/rfc7231#section-3.1.4.2) Note that Firefox and Chrome do not appear to implement this.
Content-Location HTTP header is supposed to declare unique location of the resource that was used for a response to HTTP GET (e.g. request was GET /frontpage HTTP/1.1, the server may add HTTP header Content-Location: http://domain.com/frontpage.english.msie-optimized informing the user agent that if this specific response is needed later, the provided location should be used because the original location may depend on various things, which should then be explained via the "Vary" header).
However, note that HTTP Content-Location header is problematic in real world usage because different browsers (user agents) handle it differently:
http://mail.python.org/pipermail/web-sig/2004-October/000985.html
This is because of RFC 2616 section 14.14 which says that "The value of Content-Location also defines the base URI for the entity". In short, a comforming user agent will compute the BASE URL for the fetched document using the Content-Location header which may result in different relative URLs being used if the fetched document does not define BASE url and real fetched URL and Content-Location differ enough (the "directory"/"path" part of the URL is different).
In addition, I've yet to see any advantage for using HTTP Content-Location (I once hoped that this could be used for hinting about permanent bookmark location in case currently viewed URL was volatile, such as domain.com/news/latest but that doesn't seem to be the case).
My current advice is forget about Content-Location for HTTP but you may use it for MIME email.
Section 14.14 of RFC 2616 states:
The Content-Location entity-header field MAY be used to supply the
resource location for the entity enclosed in the message when that
entity is accessible from a location separate from the requested
resource's URI...
This is used in AtomPub (RFC 5023, Section 9.2):
If the creation request contained an Atom Entry Document, and the
subsequent response from the server contains a Content-Location header
that matches the Location header character-for-character, then the
client is authorized to interpret the response entity as being a
complete representation of the newly created Entry. Without a matching
Content-Location header, the client MUST NOT assume the returned
entity is a complete representation of the created Resource.
check out RFC2557 at : http://www.faqs.org/rfcs/rfc2557.html for a deeper explanation if you are interested. I'm currently writing about this for a class. It's a little old but still relevant.