The difference between POST and GET
How important is the ability to tell the difference between data sent by POST and data sent by GET (i.e in the query string) when developing web applications? Some web frameworks (such as PHP) provide separate mechanisms for accessing POST and GET data. Others (such as Python’s cgi module) provide a single interface to form information that doesn’t distinguish between the two. I already have a strong opinion on this but I’m going to leave it open for discussion here for a bit before weighing in.
GETcan be bookmarked, andPOSTcan't be. This is a big thing if you're using search boxes and things like that. I generally make sure that all search boxes areGETand anything that's more "formish" is treated as aPOST.petrilli - 25th October 2003 04:22 - #
Mike - 25th October 2003 04:41 - #
Rich Manalang - 25th October 2003 05:05 - #
roy - 25th October 2003 05:33 - #
Fredrik Lundh - 25th October 2003 07:21 - #
My only rule: if the data is essential to navigation (like a google search), then Get is what should be chosen. Otherwise use Post. Get data is [typically] displayed in the location bar, so Get is a location only data.
Security wise there is no difference. One can easily find tools that make editing Post data as easy as snipping a URI. Is there something else?
So no, there is no difference, merely a preferance and a logical argument to what is more proper.
Stephen - 25th October 2003 07:36 - #
Using POST-based forms makes it harder for users to bookmark or pass around a query that has their password visible in it. This provides a certain modest amount of security. Similarly, POST data does not appear in web logs, whereas the full GET URL usually does. Given the places that URLs can get logged, POST makes me feel slightly more secure in general (which may be illusory).
In addition, my code tends to check anyways, because if my web pages are all coded one way and someone is feeding me queries the other way it is usually a sign that something bad is being tried. (And when I am using POST deliberately because of the above security issues, I clearly want to reject GET attempts.)
So overall: you should definitely be able to find out from the framework which way the query came in. A paranoid framework can increase security a tiny bit, at the expense of flexibility, by making people do different things in their code for GET versus POST; that way a 'wrong' query type will fail badly, no matter if the application doesn't check.
Chris S - 25th October 2003 09:11 - #
POSTs are handled differently in the browser, as you can't just "reload" them or bookmark them and the POST data doesn't appear in the browser's history. So a POST is the best option to send creds and to trigger actions (that you'd rather have happen only once).
The rule of the thumb that I use is that POSTs should be used to change the state on the server (DB, Session) or client-side state (cookies) for multi-step operations on stateless servers.
Although I don't know whether it is useful, another difference is that the POST body can be subject to a Content-Type whereas the querystring isn't.
And last, the browser is always in control of the POST body so its format is always the same, whereas you'll find many custom querystring formats on the web.
Dumky - 25th October 2003 09:29 - #
The length of the query string in GET operations is limited to an arbitary length of characters depending on the browser you're using. Also, the encoding formats differ completely. With a POST operation, you can control the MIME-type of all data sent to the server. So you can post binary data, for example.
With REST - based web services GET and POST are different operations alltogether.
These are just off the top of my head... I think there's a strong argument in favor of not throwing both operations together in the name of usability.
Not to mention that the HTTP protocol defines two seperate operations. If your application doesn't change its behaviour depending on the HTTP operation used, just do something along the lines of:
public void doGet(HttpServletRequest req, HttpServletResponse resp){doPost(req, resp);
}
That's all it should take, really ;-).
Jonas - 25th October 2003 09:33 - #
Use POST if you want to send something to the server. Use GET if you want to receive something from the server.
GET must not have side effects. Anything that does not have side effects should use GET. These are two axioms of Web architecture.
Greg H. - 25th October 2003 09:58 - #
I think that the question Simon is trying to ask is is it useful to be able to distinguish between variables that come in through the query string and variables that come in through the body of a POST request?
I agree that it's important to know the difference between the two when constructing forms, web APIs, etc. However, I can't think of a good reason to be able to distinguish between the two types of variable from the server-side script's perspective.
Even if you attempted to enforce the suggestions of RFC 2616 on the server-side (of dubious value; I think it's better enforced as a matter of practice when constructing the sending forms, etc.), then simply looking at the request method should be enough, surely?
I get the impression that Simon leans towards the differentiating point of view; that's fair enough, and it's surely better to be more flexible than necessary than too rigid to be useful. I'd just like a single example of where it would be useful, and I haven't seen one yet (off to catch up on Web-SIG now!).
Jim Dabell - 25th October 2003 13:23 - #
pete - 25th October 2003 13:27 - #
I'm working on a server-side Atom API implementation with python's WebWare and I just love how they manage the get the whole thing working: normally i don't need to distiguish between a POST or GET request so you just override witeContent() method, but when I need to I simple override respondToGet() and respondToPost() Page's method. Sweet.
Atom makes also use of PUT verb, well time to define a respondToPut() then. In this way you get the best of the worlds... Simon, I hope you'll push for this approach in the Python's Web-SIG. ^__^
dee - 25th October 2003 13:44 - #
Re: effbot,
I'm pretty sure that if you send a request such as:
---
POST http://url/cgi-bin/form?hello=1 HTTP/1.0
Content-Type: application/x-www-form-encoded
[... other headers ...]
world=1
---
It's not possible to distinguish from whence the variables came from - which is different than distinguising if it's a POST or GET operation.
Aaron Brady - 25th October 2003 14:58 - #
Fredrik Lundh - 25th October 2003 15:29 - #
Robbert Broersma - 25th October 2003 15:56 - #
When using PHP I find myself doing this alot:
if ($_SERVER['REQUEST_METHOD']=='POST') { //use $_POST } else { //use $_GET }The distinction is already available in the REQUEST_METHOD environment variable, so naming the dictionary differently doesn't really add anything, in my opinion, and in some cases can be downright annoying, like when I don't happen to care what the method is on some pages. In those cases, I have to resort to ugliness like this:
There is an extra level of indirection than necessary. What if we had to further clarify each dict with additional information already available in the environment vars like so:
if ($_SERVER['GATEWAY_INTERFACE'] == 'CGI/1.1' && $_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.0') { //use $_POST_CGI11_HTTP10['foo'] }Patrick Lioi - 25th October 2003 15:58 - #
Daniel Von Fange - 25th October 2003 16:38 - #
kellan - 26th October 2003 00:16 - #
I'm going to answer with a resounding "sometimes". I sometimes like to be able to see the difference between get and post input. Sometimes I don't care, especially for quick & dirty stuff.
In PHP I always (for all input) use a function I wrote which by default looks for a variable in both the $_POST or $_GET arrays, with $_POST preferred. If you want to limit the search, you can pass in options to restrict the search to one or the other. Works great and is easy to change, for example when something moves from a quick hack to production ;-)
The function also strips out tags, can trim to a given length, return a default value if the variable isn't there etc etc. It's an all purpose sanitizer and means the application can generally trust it's input without having to include specific checks every time.
Julian - 26th October 2003 02:11 - #
I have found it useful to be able to change forms from POST to GET on the fly using a bookmarklet.
POST to GET: Lets you send a Merriam-Webster definition link to someone. (The forms on http://www.m-w.com/ are POST forms).
GET to POST: Once, Asa was doing a simple but very long Bugzilla search, and he get a "URL too long" error. He used a modified version of that bookmarklet to change the form from GET to POST, and the search worked.
Jesse Ruderman - 26th October 2003 09:28 - #
Simon, could you please post a "summary" of this discussion?. Thanks.
ssn - 26th October 2003 13:07 - #
Adam Ashley - 27th October 2003 04:03 - #
Jesse Ruderman - 27th October 2003 08:36 - #
perhaps but the idea behind it was that the _REQUEST array contains all variables retrieved from the client system, and thus is possibly untrust worthy.
which is a much better state of affairs than the old way of ?test=1 becoming the variable $test at the top level of the script
Adam Ashley - 28th October 2003 03:06 - #
tred - 5th November 2003 07:09 - #
tiuiuguihiu - 2nd December 2003 10:02 - #
tiuiuguihiu - 2nd December 2003 10:03 - #
Apoorv - 5th May 2004 08:14 - #
karthik - 18th May 2004 05:58 - #
Muthla - 15th September 2004 15:41 - #
minu - 26th October 2004 12:34 - #
minu - 26th October 2004 12:37 - #
k - 10th January 2005 05:48 - #
Bino - 19th January 2005 10:35 - #
Ranganathan - 7th April 2005 21:29 - #
Eugeniu Amarii - 19th January 2006 18:10 - #
charlie - 11th March 2006 02:33 - #
vikrant - 31st March 2006 14:19 - #
irene - 28th April 2006 08:40 - #
nicke - 8th May 2006 17:50 - #
It's important to me, occasionally, for reasons other than those stated above.
I sometimes check to see if the method is POST at the beginning of a submission form document. If it is, I try to submit the data to the database, writing errors back to the document. Otherwise, I present the form without data filled in.
This allows me to have one .php file that doubles as both a data submission form and a form action target. So people can quickly submit a series of records without going through the whole "Thank you for your submission. Wait 3 seconds for a redirect." kabuki dance.
jhc - 12th May 2006 03:52 - #
Andres - 23rd June 2006 22:35 - #
alberto - 30th June 2006 21:44 - #
Anil Nautiyal - 18th July 2006 09:49 - #
zxcc - 19th July 2006 08:55 - #
sujoy - 19th July 2006 08:59 - #
kutu - 19th July 2006 09:11 - #
kg - 28th July 2006 05:56 - #
pRtkL xLr8r - 26th August 2006 03:41 - #
Smiffy - 18th September 2006 20:56 - #
sara freder - 2nd October 2006 20:41 - #