Button "Back back" restores empty fields

I have an x.php (in the password protected area of โ€‹โ€‹my website) that has a form and a button that uses the POST method to send form data and opens x.php#abc . It works very well.

However, if users decide to return to Internet Explorer 7, all the fields in the original x.php will be cleared and everything should be entered again. I cannot save the published information in the session, and I'm trying to figure out how I can make IE7 behave the way I want.

I searched the web and found answers that suggest that the HTTP header should contain explicit caching information. I have currently tried this:

 session_name("FOO"); session_start(); header("Pragma: public"); header("Expires: Fri, 7 Nov 2008 23:00:00 GMT"); header("Cache-Control: public, max-age=3600, must-revalidate"); header("Last-Modified: Thu, 30 Oct 2008 17:00:00 GMT"); 

and their variations. To no avail. Looking at the returned headers with a tool like WireShark shows that Apache really honors my headers.

So my question is: what am I doing wrong?

+4
internet-explorer back-button
Nov 04 '08 at 9:40
source share
6 answers

IE will save the contents of the form on the back button, and then:

  • you didnโ€™t violate caching with a pragma without a cache or the like
  • the form fields in question were not dynamically created by the script

You seem to have caching in hand, so I guess the latter can be applied. (According to mkoeller, Firefox avoids this problem if the page is in the last few reverse clicks, keeping the page alive longer than it is on the screen. However, this is not necessary, and Firefox will return to the same behavior as IE and other browsers as soon as you looked a few pages ahead and the old one expired.)

If you create your own form fields from the script onload, then the browser does not know that the new input control is โ€œthe same as the old instance, so it cannot fill its previously submitted value. In this case, if you want it to be good played using the back button, you should start storing data on the client.

Then you need to use some kind of status key so that each data set is bound only to one page instance, otherwise, through several instances of the same form or with two open browser tabs in the form, your script will be very confused right away.

And then you begin to collect a lot of data, if they are large forms, and if the client storage mechanism that you use is cookies, you can start to lose data, and also send unnecessary load to the state nonsense with every HTTP request. Other client-side storage engines are available, but they are browser dependent.

In short: making dynamically generated forms is a huge pain, and probably best avoided if you can. Having a hidden form on the page that the script creates allows the browsers to do their magic of remembering fields instead of giving you a task, usually a lot easier.

+11
Nov 04 '08 at 11:16
source share

When trying to narrow down the problem, I found the cause of my problem. I used the URLs that were rewritten by Apache (i.e. I always accessed my page as http://foo.com/page , which was displayed by Apache at http://foo.com/page.htm ). Using real URLs solved the problem and made IE7 happy if I provided the correct HTTP header ( Cache-Control , Expires , etc.).

Here is what I do in PHP code to output headers that seem to make all browsers happy with the cache:

 function emitConditionalGet($timestamp) { // See also http://www.mnot.net/cache_docs/ // and code sample http://simonwillison.net/2003/Apr/23/conditionalGet/ $gmdate_exp = gmdate('D, d MYH:i:s', time() + 1) . ' GMT'; $last_modified = gmdate('D, d MYH:i:s', $timestamp) . ' GMT'; $etag = '"'.md5($last_modified).'"'; // If the client provided any of the if-modified-since or if-none-match // infos, take them into account: $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false; $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false; if (!$if_modified_since && !$if_none_match) { return; // the client does not cache anything } if ($if_none_match && $if_none_match != $etag) { return; // ETag mismatch: the page changed! } if ($if_modified_since && $if_modified_since != $last_modified) { return; // if-modified-since mismatch: the page changed! } // Nothing changed since last time client visited this page. header("HTTP/1.0 304 Not Modified"); header("Last-Modified: $last_modified"); header("ETag: $etag"); header("Cache-Control: private, max-age=1, must-revalidate"); header("Expires: $gmdate_exp"); header("Pragma: private, cache"); header("Content-Type: text/html; charset=utf-8"); exit; } function emitDefaultHeaders($timestamp) { $gmdate_exp = gmdate('D, d MYH:i:s', time() + 1) . ' GMT'; $last_modified = gmdate('D, d MYH:i:s', $timestamp) . ' GMT'; $etag = '"'.md5($last_modified).'"'; header("Last-Modified: $last_modified"); header("ETag: $etag"); header("Cache-Control: private, max-age=1, must-revalidate"); header("Expires: $gmdate_exp"); header("Pragma: private, cache"); header("Content-Type: text/html; charset=utf-8"); } function getTimestamp() { // Find out when this page contents last changed; in a static system, // this would be the file time of the backing HTML/PHP page. Add your // own logic here: return filemtime($SCRIPT_FILENAME); } // ... $timestamp = getTimestamp(); emitConditionalGet($timestamp); emitDefaultHeaders($timestamp); //previously, this variable was mistyped as "$timestaml" 
+4
Nov 04 '08 at 2:30 p.m.
source share

Firefox does this caching. As far as I understand your question, you want IE7 to behave like Firefox does. I think that this is impossible.

Firefox and IE7 differ in how they interpret the back button.

Firefox displays the DOM tree of the previous page, since it was last shown before the page remained. That is, all form data will still be contained in the form input field. But when you click the back button, you will not see the onload .

IE7 will again display the page based on the response received from the server. So the form is emtpy (if there were no default values โ€‹โ€‹sent by the server initially), but you will see the onload .

+3
Nov 04 '08 at 10:06
source share

I poked, and this is a rather difficult problem. This is also a big pain in the ass for dynamically modified content. You visit a page, javascript completes it with instructions, you go to the next page and return, and javascript forgot. And there is no way to just refresh the page on the server side, because the page goes out of cache.

So, I developed a function to protect against the repeated pressing of a button.

Its evil and bad for the Internet, but it allows pages to behave the way people expect them to behave, rather than magically deform everywhere.

 <script type="text/javascript">//<!-- <![CDATA[ (function(){ if( document.location.hash === "" ) { document.location.hash="_"; } else { var l = document.location; var myurl = ( l.protocol + "//" + l.hostname + l.pathname + l.search); document.location = myurl; } })(); //]]> --></script> 

This will work a bit in that it detects whether the page was loaded with you / currently / browsing from the cache or not.

if this is your first time there, it will detect "no hash" and add " #_ " to the page url. if you are within the 1st time (i.e., you are not a direct link to the page), the page already has #_ on it, so it deletes it and, in the process of its removal, starts reloading the page.

+2
Nov 04 '08 at 10:45
source share

You can use autocomplete = "off" in your fields. Thus, the values โ€‹โ€‹will not be cached by the browser, so the values โ€‹โ€‹will not be filled in the form when the user clicks the back button.

+1
Nov 04 '08 at 12:12
source share

This is an old post, and a lot has changed since then. However, I had this problem with one of my forms (but with Chrome that worked up). He will clear all information if he returns. I found a workaround by complete coincidence, and I needed to share it here simply because it was so weird. This is probably not the best place to post this, but here we go.

This is what I had (a stripped-down version does not work.)

 <table> <form> <tr> <td><input type="number" value="0"></td> </tr> </form> </table> 

And that fixed it (now it works.) Moving the <form> outside of the <table> and <tr> .

 <form> <table> <tr> <td><input type="number" value="0"></td> </tr> </table> </form> 
0
Jul 10 '19 at 22:15
source share



All Articles