Flangy > Software Development > Web Note: GET after POST

GET after POST

This article has a new home at new home at AdamV.com. Thanks!

Summary: When handling a web form that was POSTed to a page, redirect away from the page to show the success message, so that the user won't get a page expired message if he tries to reload the success page.

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.