Projects » Web Notes » GET after POST

GET after POST

When handling a web form that was POSTed to a page, redirect from the POST handler to the success page. If the user reloads the success page, the "page expired" warning is avoided.

I have a page with a form that POSTs to the same page. The 2nd time around I process the POSTed data. If there are errors, then I set error flags and redisplay the page, with the form pre-filled and with error messages in place. When the form data passes through clean, I do some updates to the database.

At this point I haven't written anything out to the client yet. If I show the page now I'll get into an annoying situation. The displayed page will be a result of a POST. If the user hits reload on that page he or she will get the scary browser warning about reposting form data. In general you don't want to repost form data, because you'll end up submitting another order for a set of books.

The thing to do is to send back a redirect header. The browser will issue a GET for this new location and display the page. When you redirect a POST, the POSTed data does not travel. It can't, actually, because POSTed data is part of the request body, and a GET request doesn't have a request body.

If the user reloads the final page, the browser will reissue the GET which will just display something, not do any database updates.

Keith asks: What happens if you press back on the final page?

It gets you back to the original form, usually pulled from the browser cache, with the form refilled with the values that were submitted. This is browser dependent, of course, but late versions of IE, NS, and OmniWeb 4.1beta (finally!) behave this way.

Pressing forward from this page doesn't do a POST, but takes you straight to the result page.

What if the user hits POST again? Well, the browser will POST the data again, so you need to add server-side code to handle this case.

One thing you can do is set a cookie with some information about the transaction the first time through. If you get a POST with the cookie and similar data, you can throw out the transaction under the assumption that it's a repost. I usually keep some time info in the cookie, and throw out the POST if it comes within N seconds of the first one.

HTTP Note

There is more than one way to signal a redirect. HTTP/1.1 provides a specific code, 303 See Other to use in the case of redirecting after a POST:

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.
There may be browser compatibility issues with using a "303 See Other" response instead of a more basic redirect response. I use "302 Found" in my scripts.

Sightings


Contact Information