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.1
and in the body of POST requests:
POST /blog/ HTTP/1.1
GET vs POST Basics
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?
Simply put, because GET requests are more useable:
- GET requests can be cached
- GET requests can remain in the browser history
- GET requests can be bookmarked
- GET requests can be distributed & shared
- GET requests can be hacked (ask Jakob!)
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.
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.