HTTP POST requests supply additional data from the client (browser) to the server in the message body. In contrast, GET requests include all required data in the URL. Forms in HTML can use either method by specifying method="POST" or method="GET" (default) in the <form> element. The method specified determines how form data is submitted to the server. When the method is GET, all form data is encoded into the URL, appended to the action URL as query string parameters. With POST, form data appears within the message body of the HTTP request.
|History||Parameters remain in browser history because they are part of the URL||Parameters are not saved in browser history.|
|Bookmarked||Can be bookmarked.||Can not be bookmarked.|
|BACK button/re-submit behaviour||GET requests are re-executed but may not be re-submitted to server if the HTML is stored in the browser cache.||The browser usually alerts the user that data will need to be re-submitted.|
|Encoding type (enctype attribute)||application/x-www-form-urlencoded||multipart/form-data or application/x-www-form-urlencoded Use multipart encoding for binary data.|
|Parameters||can send but the parameter data is limited to what we can stuff into the request line (URL). Safest to use less than 2K of parameters, some servers handle up to 64K||Can send parameters, including uploading files, to the server.|
|Hacked||Easier to hack for script kiddies||More difficult to hack|
|Restrictions on form data type||Yes, only ASCII characters allowed.||No restrictions. Binary data is also allowed.|
|Security||GET is less secure compared to POST because data sent is part of the URL. So it's saved in browser history and server logs in plaintext.||POST is a little safer than GET because the parameters are not stored in browser history or in web server logs.|
|Restrictions on form data length||Yes, since form data is in the URL and URL length is restricted. A safe URL length limit is often 2048 characters but varies by browser and web server.||No restrictions|
|Usability||GET method should not be used when sending passwords or other sensitive information.||POST method used when sending passwords or other sensitive information.|
|Visibility||GET method is visible to everyone (it will be displayed in the browser's address bar) and has limits on the amount of information to send.||POST method variables are not displayed in the URL.|
|Cached||Can be cached||Not cached|
Differences in Form Submission
The fundamental difference between METHOD="GET" and METHOD="POST" is that they correspond to different HTTP requests, as defined in the HTTP specifications. The submission process for both methods begins in the same way - a form data set is constructed by the browser and then encoded in a manner specified by the enctype attribute. For METHOD="POST the enctype attribute can be multipart/form-data or application/x-www-form-urlencoded, whereas for METHOD="GET", only application/x-www-form-urlencoded is allowed. This form data set is then transmitted to the server.
For form submission with METHOD="GET", the browser constructs a URL by taking the value of the action attribute, appending a ? to it, then appending the form data set (encoded using the application/x-www-form-urlencoded content type). The browser then processes this URL as if following a link (or as if the user had typed the URL directly). The browser divides the URL into parts and recognizes a host, then sends to that host a GET request with the rest of the URL as argument. The server takes it from there. Note that this process means that the form data are restricted to ASCII codes. Special care should be taken to encode and decode other types of characters when passing them through the URL in ASCII format.
Submission of a form with METHOD="POST" causes a POST request to be sent, using the value of the action attribute and a message created according to the content type specified by the enctype attribute.
Pros and Cons
Since form data is sent as part of the URL when GET is used --
- Form data are restricted to ASCII codes. Special care should be taken to encode and decode other types of characters when passing them through the URL in ASCII format. On the other hand, binary data, images and other files can all be submitted through METHOD="POST"
- All form data filled in is visible in the URL. Moreover, it is also stored in the user's web browsing history/logs for the browser. These issues make GET less secure.
- However, one advantage of form data being sent as part of the URL is that one can bookmark the URLs and directly use them and completely bypass the form-filling process.
- There is a limitation on how much form data can be sent because URL lengths are limited.
- Script kiddies can more easily expose vulnerabilities in the system to hack it. For example, Citibank was hacked by changing account numbers in the URL string. Of course, experienced hackers or web developers can expose such vulnerabilities even if POST is used; it's just a little bit harder. In general, the server must be suspicious of any data sent by the client and guard against Insecure Direct Object References.
Differences in Server-Side Processing
In principle, processing of a submitted form data depends on whether it is sent with METHOD="GET" or METHOD="POST". Since the data is encoded in different ways, different decoding mechanisms are needed. Thus, generally speaking, changing the METHOD may necessitate a change in the script which processes the submission. For example, when using the CGI interface, the script receives the data in an environment variable (QUERYSTRING) when GET is used. But when POST is used, form data is passed in the standard input stream (stdin) and the number of bytes to be read is given by the Content-length header.
What happens when GET and POST variables conflict?
In some languages such as PHP, the information from GET and POST parameters, in addition to being available separately, is also combined into a convenience variable e.g., $_REQUEST in PHP. If there is a conflict—i.e., the same parameter name is used with different values in GET and POST—then the conflict is resolved with certain rules. In the case of PHP, precedence is decided by the variables_order configuration directive. The default order is EGPCS (environment, GET, POST, Cookie, Server). This means the variable in $_GET gets precedence over $_POST, which in turn gets precedence over $_COOKIE.
GET is recommended when submitting "idempotent" forms - those that do not 'significantly alter the state of the world'. In other words, forms that involve database queries only. Another perspective is that several idempotent queries will have the same effect as a single query. If database updates or other actions such as triggering emails are involved, the usage of POST is recommended.
From the Dropbox developer blog:
a browser doesn’t know exactly what a particular HTML form does, but if the form is submitted via HTTP GET, the browser knows it’s safe to automatically retry the submission if there’s a network error. For forms that use HTTP POST, it may not be safe to retry so the browser asks the user for confirmation first.
A "GET" request is often cacheable, whereas a "POST" request can hardly be. For query systems this may have a considerable efficiency impact, especially if the query strings are simple, since caches might serve the most frequent queries.
In certain cases, using POST is recommended even for idempotent queries:
- If the form data would contain non-ASCII characters (such as accented characters), then METHOD="GET" is inapplicable in principle, although it may work in practice (mainly for ISO Latin 1 characters).
- If the form data set is large - say, hundreds of characters - then METHOD="GET" may cause practical problems with implementations which cannot handle that long URLs.
- You might wish to avoid METHOD="GET" in order to make it less visible to users how the form works, especially in order to make "hidden" fields (INPUT TYPE="HIDDEN") more hidden by not appearing in the URL. But even if you use hidden fields with METHOD="POST", they will still appear in the HTML source code.
What about HTTPS?
Updated May 15, 2015: Specifically when using HTTPS (HTTP over TLS/SSL), does POST offer any more security than GET?
This is an interesting question. Say you make a GET request to a webpage:
Assuming that your Internet connection is being monitored, what information about this request will be available to the snooper? If POST is used instead, and the user and passwd data is included in POST variables, will that be more secure in the case of HTTPS connections?
The answer is no. If you make such a GET request, only the following information will be known to the attacker monitoring your web traffic:
- The fact that you made an HTTPS connection
- The hostname – www.example.com
- The total length of the request
- The length of the response
The path part of the URL — i.e., the actual page requested, as well as the query string parameters — are protected (encrypted) while they are "over the wire" i.e., in transit on their way to the destination server. The situation is exactly the same for POST requests.
The POST method does still retain one advantage even in the case of HTTPS, however. Web servers tend to log the entire requested URL in plain text in their access logs; so sending sensitive information over GET is not a good idea. This applies irrespective of whether HTTP or HTTPS is used.