Tuesday, May 17, 2005

Choosing between GET and POST

User Registration and Management: "Choosing between GET and POST
Following an ordinary hyperlink on an HTML page results in a GET request to the server under the HTTP protocol. When programming a page with an HTML form you have a choice between using METHOD=GET and METHOD=POST. A heavy reliance on POST will result in a site that breaks the browser Back button. An attempt to go back to a page that was the result of a POST will generally bring up a 'Page Expired' error message and possibly a dialog box asking whether the user wishes to resubmit information by using the 'Refresh' button.

Some of our students asked for further guidance on how to choose between GET and POST and here's the response from Ben Adida, part of the course's teaching staff in Fall 2003:

Most of you may be wondering, why GET vs. POST in submitting forms?
Oftentimes, one will use POST just to keep pretty URLs (without
?var=val&var=val). But that's the wrong way to think about it.

A GET implies that you are getting information. You can resubmit a GET
any number of times: you are just querying information, not performing
any actions on the back-end.

A POST implies that you are performing some action with side-effect:
inserting a row, updating a row, launching a missile, etc... That's
why when you try to reload a POST page, your browser warns you: are
you sure you want to launch another missile?

In general, you should strive to respect the above principles. Here are
two key examples:
- searching users or content. That should be a GET.
- Inserting a user or updating a profile. That should be a POST.

Of course, HTML and HTTP have some restrictions that complicate things:

a) GET forms are limited in length by how much your browser can send
in a URL field. This can be a problem for very complicated search
forms, though probably not an issue at this stage. If you do hit
that limit though, then it's okay to use a POST.

b) POST forms can only be performed by having an HTML button, or by
using JavaScript to submit a form. JavaScript is not ideal. Thus,
sometimes you want to have a link that is effectively an action
with side-effect (e.g. "ban user"), but you make it a GET.

You can use redirects (HTTP return code 302) to make your life easier.
The nice thing about correct 302's is that the URL that issues a 302 is
never kept in a browser's history, so it is never queried twice unless
the user does something really conscious (like click back and actively
resubmit the form). Specifically:

1) when you POST data for an insert or update, have your script
process the POST, then redirect to a thank-you page. That way,
if the user clicks "reload", they are simply reloading the
thank-you page, which is just a GET and won't cause side-effects
or warnings. You can also redirect to something more meaningful,
perhaps the list of recently registered users once you've edited
one.

2) when you use a GET link to actually perform an action with
side-effect, you can also have that target script perform its
action then immediately redirect to a script with no side
effects. This will prevent the accidental repetition of an
action.

Scripts that have side effects should not be reachable at URLs that
may enter the cache and be randomly re-requested by the browser. The
one exception is if the POST causes some kind of error: it's mostly
okay for the script that processes the POST to display the error
instead of redirecting to some kind of error-displaying page (which
would be clunky to build anyways).

.NET folks: when you use ASP.NET and postback, you have no choice of
method: it's always POST. Remember to follow the above rule for POST:
you can have your handler method perform the side-effects but it
should then redirect somewhere else instead of returning content.

I hope this helps in making your sites more usable. Let me know if
you have any questions.

-Ben

PS: None of the above solves the "double-click" problem which is what
happens if a user double-submits a form quickly (especially those
users who don't know the difference between single and double
clicking). We'll talk about double-click protection later.
Post a Comment