HEADS UP: Header Redirection http status codes

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

HEADS UP: Header Redirection http status codes

Post by Benjamin »

I just wanted to give everyone a heads up regarding HTTP status codes and an issue I encountered with Google Chrome.

It's not unusual to redirect a user after they have logged in. Reference the following code:

Code: Select all

 
function redirect($url) {
    header("Location: $url");
}
 
The above code will redirect a user to the destination with no perceived issue. An issue does occur however with google chrome, because it appears to adhere to the HTTP standards more precisely.

Using PHP's header function to send a location tag will result in an HTTP status code of 302 being sent by default, unless you have already sent a 3xx status code. So what does this mean? It means that the browser can cache the result of the request resulting in future requests immediately requesting the url sent by the previous redirection header.

So if you request login.php, get redirected to account.php, then request login.php again, login.php will not be requested. Instead, the browser will directly request account.php.

In most cases this will not make any difference. I noticed that closing the session will clear the 302 redirection cache in Google Chrome. This issue became apparent to me because I had a page that redirected to another page for logged in users when specific criteria was not being met. I noticed that they were still being redirected even after the criteria was being met. Since the destination page was not redirecting them, I realized that Google Chrome was caching the redirect.

My first attempt to resolve this issue was to change the redirection status code to "307 Temporary Redirect". This caused issues in Firefox when I submitted a form. Firefox would ask me if I wanted to resubmit the post data to the new url.

I then reviewed the status codes on w3.org and discovered that for 302 redirects the response is ONLY cacheable if indicated by the Cache-Control or Expires header.
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 final solution was to send the Cache-Control and Expires headers, along with the 302.

Code: Select all

 
function redirect($url)
{
    header("Cache-Control: max-age=0, no-cache, no-store, must-revalidate"); // HTTP/1.1
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
    header("Location: $url", true, 302);
    exit();
}
 
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: HEADS UP: Header Redirection http status codes

Post by Christopher »

Interesting. Do you see this as how we will need to do redirects once other browsers become stricter about this -- like Chrome?
(#10850)
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: HEADS UP: Header Redirection http status codes

Post by Eran »

Are we talking about the Chrome beta?
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: HEADS UP: Header Redirection http status codes

Post by Benjamin »

arborint wrote:Interesting. Do you see this as how we will need to do redirects once other browsers become stricter about this -- like Chrome?
I believe so, but more research should be done. The default headers the server is sending are:
HTTP/1.1 200 OK
Date: Wed, 19 Aug 2009 08:24:53 GMT
Server: Apache/2.2.13 (Unix) mod_ssl/2.2.13 OpenSSL/0.9.8e-fips-rhel5 DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635
X-Powered-By: PHP/5.2.10
Transfer-Encoding: chunked
Content-Type: text/html
By default the server is not sending Cache-Control or Expires headers. So it looks like Chrome is caching the redirect because it isn't being told not to. I'll have to get back with the version, but I don't believe it's a beta.
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.
According to the standard above, the browser should not cache the result UNLESS it is told that it should. It appears Chrome is caching it for the duration of the session.
User avatar
arjan.top
Forum Contributor
Posts: 305
Joined: Sun Oct 14, 2007 4:36 am
Location: Hoče, Slovenia

Re: HEADS UP: Header Redirection http status codes

Post by arjan.top »

"alternative" status code to 302 is 303 not 307
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: HEADS UP: Header Redirection http status codes

Post by Benjamin »

arjan.top wrote:"alternative" status code to 302 is 303 not 307
I believe you are correct.

I was also referencing this post on php.net. I found it to be quite interesting, since I've never seen a browser cache redirect responses up until I discovered this issue with Google Chrome.

That said, if Chrome is caching 302 redirects for the duration of a session, then we would need to specify the status code when redirecting if the destination of a redirect can change during the duration of a session.

So then the code could be:

Code: Select all

 
function redirect($url) {
    header("Location: $url", true, 303);
    exit();
}
 
Just so we are all on the same page, here are the status codes: http://www.w3.org/Protocols/rfc2616/rfc ... ml#sec10.3
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: HEADS UP: Header Redirection http status codes

Post by Christopher »

So does the 303 work the same as the 302 code above that set headers?
(#10850)
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: HEADS UP: Header Redirection http status codes

Post by Benjamin »

According to the specs it should, but I haven't tested it yet.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Re: HEADS UP: Header Redirection http status codes

Post by s.dot »

I see this in the newest version of firefox. I have header('Location: xxx') sprouted everywhere throughout my procedural codes :( dunno if there's a hack i can do to add in this new code easily or not.

EDIT| I wonder if setting the header for every page (such as in a global file before the page is output - and included on every page) not to cache will work the same? I don't have time to go through and change all of my header('Location....') lines.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: HEADS UP: Header Redirection http status codes

Post by Benjamin »

Setting these should work:

Code: Select all

 
header("Cache-Control: max-age=0, no-cache, no-store, must-revalidate"); // HTTP/1.1
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
 
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Re: HEADS UP: Header Redirection http status codes

Post by s.dot »

astions wrote:Setting these should work:

Code: Select all

 
header("Cache-Control: max-age=0, no-cache, no-store, must-revalidate"); // HTTP/1.1
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
 
It does not work in my particular situation which is currently click a link that goes to an intermediary script (using get parameters - i know this is against the specs) and then redirects back to original script.

e.g. in admin.php i click a link that goes to _prg-admin.php?a=rejectbanner&banid=3 which updates the database accordingly and redirects back to admin.php

so this is i guess get-redirect-nothing

but in either case, i guess i'll have to try to update the header('Location: ') call.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: HEADS UP: Header Redirection http status codes

Post by Benjamin »

Ok, a few things..

1. The browser knows that when it requested redirect.php it was redirected to blah.php?foo=bar. In this case, the redirect needs to send either a 303 code or the cache control code that I posted earlier. Otherwise, the browser will simply request blah.php?foo=bar again, even if the parameters are changed.

2. I'm not sure the browser should be caching it at all if it's a post request to the redirection page.

3. blah.php may be responding with a not-modified header, or the browser is caching it. In this case, you'll need to send the cache control headers on the landing page.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Re: HEADS UP: Header Redirection http status codes

Post by s.dot »

OK, a combination of both seemed to work.. neither by themselves seemed effective.

No cache headers on the page, header location call with true, 303 in the redirect.

I'm not really up to date on these cache and header status things. If I decide to go ahead and the ",true, 303" to redirects that are done through a real post-redirect-get ... will this hurt anything?
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: HEADS UP: Header Redirection http status codes

Post by Benjamin »

scottayy wrote:If I decide to go ahead and the ",true, 303" to redirects that are done through a real post-redirect-get ... will this hurt anything?
I wouldn't think so offhand. My thoughts are that Firefox should not be caching a page that was sent POST data, even if it returns a redirect. So that almost sounds like a bug. You do need to be conscious of the status code that you send however, due to the differences in the way search engines handle them. You'll want to review 10.3 Redirection 3xx http status codes, as well as this post on php.net.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Re: HEADS UP: Header Redirection http status codes

Post by s.dot »

It is indeed doing it on POST data with the p-r-g pattern. However I've looked into the problem further using the same version of firefox on another computer with the same operating system. It's not a problem on that computer. I've also just installed chrome (what the original post was about) and it is not having this problem either.

It seems it's related to the firefox install I have on my new pc (though a fresh install - or a new profile) does not fix the problem. Very weird.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
Post Reply