PHP search resend data on back button


I have a custom built CMS that I inherited with a site I bought, the system itself works very well apart from one thing the site search facility.

When the list of pages is displayed the user clicks one of the results, if they then wish to go back to the results they are presented a Document Expired page asked to resend the data.

What can I do to retain the search results for the user on the back button?

Thanks John

That is a security feature of the user’s browser, and not something you can override. Assuming of course you’re talking about the default “data has expired page”.

I always thought there was a few things that could be done, 1) you could manually set the page’s expiration date so be hours or days in the future, thus telling the browser it’s okay to show it. 2) To get around the re-send post data message, I’ve stored the results I want to display or the post data for that matter in a session and redirected to the search results page to display the list of results. This in effect removes the post data from the initial page request so if you navigate away, you can safely use the back button (assuming the session data is still present).

An adjustment I’ve been seeing with #2 is storing the search criteria in a table, and redirecting to the results page passing the search criteria row id in the URL, this way you have a way to get to the page without using session data.

Thanks for the reply, the same issue across all browsers, maybe I have not explained myself correctly, if you search in Google click a result and then hit the back button you are presented with the same search as before, this also happens in other CMS such a Joomla, but on my site it doesn’t, am I right in thinking this has something to do with $_POST and $_GET ??

How does either of these stop the browser from saying “I sent data to this page. You pushed the back button. I need to make sure you want to send it again.”?

The first wouldn’t, but would get rid of the expired message (I think).

The second would because the page you are going back to wasn’t the recipient of the posted data. Consider the following workflow:

  1. Data is posted to search.php
  2. search.php writes the posted data to a search table and redirects the user to searchresults.php?id=X
  3. User sees searchresults.php?id=X and clicks on a link
  4. User uses back button to go back to searchresults.php?id=X (no warning shown because that page was redirected to, not posted to)

This… is partially true (or so Google tells me. Learn something new everyday, kiddies!). It depends entirely on what Redirection code is sent to the browser;
302/303 are okay, and send a GET.
301/307 are not, and send a POST after reconfirmation.

Hey guys, I think you are making it out to be more complicated than it really is :). The OP is right that it’s about POST/GET. The expiration notice is standard behaviour of browsers when you send a form using POST, leave the page and then go back. The reason is that browsers do not store POST data in history so they cannot property repeat the same POST request. However, data sent using GET are stored in history because GET data become part of the URL so such requests can be easily repeated by the browser when going back/forward. So the solution is to change the search form and the result page to use GET instead of POST and that’s what google does.

Edit: to be more precise, browsers may cache POST data temporarily but even when they do they usually warn users that the data need to be re-submitted. This is because POST requests should be used when they actually cause some change in the system, for example you insert data to the database, delete a record, etc. Therefore, repeating the POST request without warning imposes a risk of undesirable action being performed for the second time. For requests that do not change anything in the target system, like search results (they only fetch data), GET should be used. Because GET requests don’t (read: shouldn’t) change the taget system state browsers can safely resend them without warning.

When you have done that you can go a step further and set the HTTP headers of the result page so that it is not re-downloaded on hitting the back button. You may get inspired by headers sent by google:

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 24 Jan 2013 14:11:47 GMT
Expires: -1
Server: gws
Set-Cookie: PREF=ID=bdd9f4621316b989:U=ed51d8e7c619f888:FF=4:LD=pl:CR=2:TM=1331729163:LM=1359036707:GM=1:SG=1:S=W5y2DmtvP6dH3_Pq; expires=Sat, 24-Jan-2015 14:11:47 GMT; path=/;
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Firefox-Spdy: 3

The important one is cache-control and also Expires. When cache-control is set to private and no no-cache directives are used then most browsers fetch the fresh page when you navigate to it via a link or form submission but will display it from cache when you press the back or forward button - this is what is usually desired for search result pages. In php you do it like this before sending output:

header("Cache-Control: private, max-age=0");
header("Expires: -1");