The Definitive Guide to GET vs POST

Unfortunately there is a lot misuse of GET over POST and vice versa. Both HTTP methods can achieve the same goals, but an incorrect choice between them can lead to unexpected and potentially harmful outcomes.

So, to make sure we get things right, I present to you the definitive guide of choosing between GET and POST.

Editor’s Note: Mike McDerment of FreshBooks.com will be teaching a 1/2 day workshop on ‘How to Build a Web App from A-Z’ at The Future of Web Apps.

Note: Remember that query strings (i.e. name/value pairs) get transferred in the URL of GET requests:

GET /blog/?name1=value1&name2=value2 HTTP/1.1Host: carsonified.com

and in the body of POST requests:

POST /blog/ HTTP/1.1Host: carsonified.comname1=value1&name2=value2

GET vs POST Basics

In between new additions to our vocabularies (think “idempotent“), sections 9.1, 9.3 & 9.5 of RFC 2616 help us to conclude the first rule of GET vs POST…

Rule #1: Use GET for safe actions and POST for unsafe actions.

The RFC instructs internet browsers to make users aware that, when reissuing a previously made POST request, that the action (e.g. placing an order) is potentially unsafe. Hence the existence of dialogue boxes like this:

However, whilst browser compliance with this RFC instruction might explain why POST should be used for unsafe actions, why shouldn’t we use POST for safe ones?

Note: If you need the best of both worlds, an unsafe action can be made safe by making it idempotent, so that it makes no difference how many times it’s requested. You do this by giving the request a unique ID and using server-side validation to ensure that a request with that ID hasn’t already been processed. In fact, if you’re in search of excellence, all unsafe actions should be made idempotent as nothing can stop users from ignoring warnings.

GET vs POST Extended

Rule #2: Use POST when dealing with sensitive data.

Because query strings are transferred openly in GET requests, we have to consider our security and that of our users when dealing with sensitive data like passwords or credit card numbers:

Our users… because they may not realise that they are sharing sensitive data when they share a URL or that it can be viewed in the browser history by other people using the same computer.*

Ourselves… because we may be breaking laws by unexpectedly storing data that we’re not allowed to (like credit card CV2s) in log files.

* This doesn’t apply when working within an AJAX environment.

Rule #3: Use POST when dealing with long requests.

Although the RFC doesn’t lay down any length-related guidelines, Internet Explorer – with its insistence on finding ways to make things difficult for us – enforces a maximum URL length of 2,048 characters.

Rule #4: Use GET in AJAX environments.

When using XMLHttpRequest, browsers implement POST as a two-step process (sending the headers first and then the data). This means that GET requests are more responsive – something you need in AJAX environments.

Summary

Although rules usually exist for good reasons, it’s good to know the logic behind them so they can be embraced fully. I, myself, hate rules that don’t have explanations and I hope that the above helps to justify the rules of GET vs POST.

Choosing between methods is a systematic process which should be part of second nature.