2

http://discoursedb.org/wiki/Special:RunQuery/Item_query

The above link has a form where if you enter a search item and click on any links in the result and then the back button the results are still there.

I have an identical form with additional fields (dropdown and checkboxes) where the back button doesn't work and the browser asks for confirmation to submit the data again.

What can cause this?

Update: I just noticed that if I open Console in Chrome and test my implementation it works when cache is disabled and not otherwise. Maybe this helps in explaining the behavior?

Niks
  • 21
  • 1
  • 3
  • 1
    One reason could be if you are using PHP and $_POST. Are you? Can you share some source pls? – Alex Szabo Aug 26 '14 at 13:25
  • its just saves the value on server when you hit button...when you click *back*, saved values are stored back in their input boxes with help of those variables... – NoobEditor Aug 26 '14 at 13:27
  • 2
    It's because you use POST. [This is what happening to you](http://en.wikipedia.org/wiki/File:PostRedirectGet_DoubleSubmitProblem.png) and [this is what you should do](http://en.wikipedia.org/wiki/File:PostRedirectGet_DoubleSubmitSolution.png) – Déjà vu Aug 26 '14 at 13:28
  • @Déjàvu: but [the OP’s comparison link](http://discoursedb.org/wiki/Special:RunQuery/Item_query) that *doesn’t* produce the browser warning about resubmitting data doesn’t redirect the user after the form submission (at least according to Chrome Web Inspector’s network tab on my computer). It returns 200 OK directly from the `POST` request. – Paul D. Waite Aug 26 '14 at 13:30
  • @PaulD.Waite Maybe you commencted to soon before i editted my answer. But if you look at the 2nd link it's doing a post as well. However it won't be sending a 2nd form into the database upon refreshing opr page backing thus not asking for a confimation. – Déjà vu Aug 26 '14 at 13:32
  • @Déjàvu: maybe you replied too soon before I edited my comment in response to your comment edit! – Paul D. Waite Aug 26 '14 at 13:34
  • @PaulD.Waite Hmm, i had this problem once and I fixed it with what i linked. I don't know what else could be done to fix the refresh/double database input. And if it's faster than the redirect method. – Déjà vu Aug 26 '14 at 13:36
  • @Déjàvu: I agree that your solution is usually correct. What I don’t understand is why I *don’t* get the usual browser warning about form resubmission when clicking back from a search result on [Nik’s example page](http://discoursedb.org/wiki/Special:RunQuery/Item_query). – Paul D. Waite Aug 26 '14 at 13:37
  • @PaulD.Waite exactly... – Déjà vu Aug 26 '14 at 13:38
  • In the example link going back simply restores the HTML from the cache.. Why/How does that work? – Niks Aug 26 '14 at 13:42

2 Answers2

3

Don't return a document from the result of a POST. Instead, return a redirect to a document. This helps solves many of these issues. That's also what causes form re-submission warnings. When you click back, you skip redirected links, but you do not skip 200 OK responses. So if you are replying with 200 OK for your POST requests, you might be doing it wrong. Reply with a 303 See Other or something similar, with the actual document URL in the Location header.

More detail:

POST requests are not typically cacheable. POST requests are for performing some operation or adding some data. If you make the same request again, you want to perform the operation again or add some new data.

GET requests typically are cacheable. GET requests are for fetching resources. When you request a resource at a specific URL, it is generally expected that same document will be returned if you make the same request again.

Either way, the server is going to respond with one of several status codes. The most common is 200 OK, which tells the browser that everything went fine with the request and to display the response to the user.

The next most common is a redirect. There are several varieties, but some of the most common are 301 Moved Permanently (appropriate when you are sending them to a canonical URL), 302 Found (sort of a catch all), and 303 See Other (this is typically what you want in response to a successful POST). For all of these redirect cases, the Location header will contain a URL the browser should redirect to.

Currently, you are sending back a 200 OK result for the POST request. This tells the browser that the response should be displayed to the user. But because it's a POST request, the browser will not cache the response. And you will get form re-submit warning because in order to refresh the page, you have to send the POST request and all its data all over again.

What SHOULD happen is the POST request responds with a 303 See Other and a URL in the Location header pointing to the response document. When the browser sees the redirect, it will issue a GET request against this URL, which is cacheable and will not cause form re-submission issues when you try to refresh.

You may want to read the following for some more background.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Rich Remer
  • 2,123
  • 1
  • 21
  • 22
  • Wow! this answer is so generic that its of no benefit to me. Please see the comments in the question. – Niks Aug 26 '14 at 18:54
  • I added some detail. The comments would indicate that cache control headers are being used in the POST scenario, but using cache control headers to change the behavior of GET/POST is going against the grain. Just go with the HTTP flow and things will work as expected. – Rich Remer Aug 26 '14 at 22:32
  • @RichRemer: the thing is, if you look at [Nik’s first example link](http://discoursedb.org/wiki/Special:RunQuery/Item_query), you’ll notice that it returns 200 from the search post request. When I click on a search result and then click back, I’d expect to get the browser warning about resubmitting a form, but I don’t (at least in Chrome 36 on OS X). Do you know why? – Paul D. Waite Aug 27 '14 at 09:17
  • It's the "Cache-Control: private, must-revalidate, max-age=0" in the headers. As I mentioned, you can use Cache-Control headers to control this stuff, but there are browser differences in how they are handled and it's fighting a problem that simply wouldn't exist if HTTP were being used as suggested. – Rich Remer Aug 27 '14 at 16:48
  • @RichRemer: cool cool, I’ll test that myself later on. Do you know why that cache control header has that effect? It sounds to me like it says “Don’t cache this response”, which I’d expect to *cause* a re-posting of the form (and thus a warning), if anything. – Paul D. Waite Aug 29 '14 at 12:52
  • I suspect it's because with those Cache-Control headers, the browser is bypassing the cache entirely. I imagine the form re-submit warning is probably a hook related to loading pages from cache. When the cached result is about to be loaded, the user is given an option to display the cached result (say No to resubmit) or to get a fresh copy from the server (say Yes to resubmit). – Rich Remer Aug 29 '14 at 16:50
0

Its because your server has disabled Caching. This is an old post but the problem still prevails. Regardless of whether you respond to your POST with a page or a redirect Chrome will still block the back button if you have disabled Caching and this means backing into a form POST. In other browsers they simply go back through your history and return the last GET request ignoring the POST/form submission. In the case of Chrome it does not. You can try it by simply re-enabling Caching and Chrome will return the Cached responses from your POST requests. Chrome DOES cache post responses (See the attached image) but only if you have allowed it to.

enter image description here

How to enable/disable Caching

That is another topic but it's done most consistently by sending headers from the server-side that instruct the client not to cache the response. Simply adding headers to your meta tags in HTML is not effective in all scenarios but that is a possible place to "attempt" to prevent caching. An example for Java developers which can be ported to other languages. Java servlet how to disable caching of page

Community
  • 1
  • 1
Usman Mutawakil
  • 4,993
  • 9
  • 43
  • 80