HTTP中的GET跟POST区别分析详解

HTTP中的GET和POST区别分析详解
1.数据发送形式
使用POST请求,数据在请求体(REQUEST HEADER)中传递给服务器。使用GET请求,数据将编码到URL中。
注意:POST请求的URL也可是http://www.example.com/index.php?a=hello&b=world的形式,只是其发送的数据将在请求体中。GET请求会把发送的数据编码后加在URL后,无论此前URL长什么样子。
2.什么时候使用GET和POST
GET 适用于多数请求,而POST 仅用于更新站点。根据 HTTP 规范,GET 用于信息获取,而且应该是幂等的。也就是说,当使用相同的URL重复GET请求会返回预期的相同结果时,GET方法才是适用的。当对一个请求有副作用的时候(例如,提交数据注册新用户时),应该使用POST请求而不是GET。[参考2]
3.URL长度问题
RFC 2616、 " 超文本传输协议 -- HTTP /1.1, " 未指定任何对 URL 长度要求。
Microsoft Internet Explorer 具有统一资源定位器 (URL) 长度的 2,083 字符。 InternetExplorer 也有路径长度为 2,048 字符。如果使用 GET 方法, 您仅限于最多 2,048 字符, 减去实际路径中的字符数。[参考3]。网上流传256,1k等长度URL限制,可能对于以前古老的浏览器,现在应该纠正了,大概上对于IE是2k。
URL长度限制适用于 POST 请求和 GET 请求 URL。
对使用GET方法提交数据时,在IE环境下,需要注意其数据编码加到URL后其长度受到2083字节的限制。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。POST提交数据大小理论没有限制,HTTP协议规范也没有进行大小限制。“POST数据量存在128K的大小限制”不够准确,POST数据是没有限制的,起限制作用的是服务器的处理程序的处理能力[参考1]。
4.GET请求的安全性
对于GET请求,其数据将附加在URL中,在浏览器地址栏中会显示出来。在用户登录时,其用户名和密码等信息将显示在浏览器地址栏中,若登录页面被浏览器缓存或者被浏览器历史记录则其他用户可以通过此机器拿到用户信息。而对于网络传输数据层面来讲,GET和POST安全性是没有太大区别的。
GET请求发送数据时,其数据是需要进行URL编码的,一些字符会发生改变,在服务端接受时需要做URL解码处理。对于某些WEB服务器,其GET请求会记录在服务器上,如果里面含有隐私数据将有可能被第三方获取[参考5]。

附件一:
[参考6]
HTTP协议中GET方法和POST方法是有所不同的,RFC1945中的英文原文如下:
8.1 GET
The GET method means retrieve whatever information (in the form of an
entity) is identified by the Request-URI. If the Request-URI refers
to a data-producing process, it is the produced data which shall be
returned as the entity in the response and not the source text of the
process, unless that text happens to be the output of the process.
The semantics of the GET method changes to a "conditional GET" if the
request message includes an If-Modified-Since header field. A
conditional GET method requests that the identified resource be
transferred only if it has been modified since the date given by the
If-Modified-Since header, as described in Section 10.9. The
conditional GET method is intended to reduce network usage by
allowing cached entities to be refreshed without requiring multiple
requests or transferring unnecessary data.

8.3 POST
The POST method is used to request that the destination server accept
the entity enclosed in the request as a new subordinate of the
resource identified by the Request-URI in the Request-Line. POST is
designed to allow a uniform method to cover the following functions:
     o Annotation of existing resources;
     o Posting a message to a bulletin board, newsgroup, mailing list,
or similar group of articles;
     o Providing a block of data, such as the result of submitting a
form [3], to a data-handling process;
     o Extending a database through an append operation.
The actual function performed by the POST method is determined by the
server and is usually dependent on the Request-URI. The posted entity
is subordinate to that URI in the same way that a file is subordinate
to a directory containing it, a news article is subordinate to a
newsgroup to which it is posted, or a record is subordinate to a
database.
A successful POST does not require that the entity be created as a
resource on the origin server or made accessible for future
reference. That is, the action performed by the POST method might not
result in a resource that can be identified by a URI. In this case,
either 200 (ok) or 204 (no content) is the appropriate response
status, depending on whether or not the response includes an entity
that describes the result.
If a resource has been created on the origin server, the response
should be 201 (created) and contain an entity (preferably of type
"text/html") which describes the status of the request and refers to
the new resource.
A valid Content-Length is required on all HTTP/1.0 POST requests. An
HTTP/1.0 server should respond with a 400 (bad request) message if it
cannot determine the length of the request message's content.
Applications must not cache responses to a POST request because the
application has no way of knowing that the server would return an
equivalent response on some future request.

翻译成中文(黄晓东翻译,xdhuang@eyou.com)就是
8.1 GET
GET方法就是以实体方式得到由请求URI所指定资源的信息。如果请求URI只是一
个数据产生过程,那么最终要在回应实体中返回的是由该处理过程的结果所指向
的资源,而不是返回该处理过程的描述文字,除非那段文字恰好是处理的输出。
如果请求消息包含If-Modified-Since标题域,GET方法的语法就变成“条件GET”,
即“(conditional GET)”。 条件GET方法可以对指定资源进行判断,如果它在
If-Modified-Since标题域(见10.9节)中的指定日期后发生了更新,才启动传
输,否则不传输。这种条件GET允许被缓存的实体在不必经过多次请求或不必要
的数据传输就能进行刷新,从而有助于降低网络负载。
8.3 POST
POST方法用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它
当作请求队列(Request-Line)中请求URI所指定资源的附加新子项。POST被设计
成用统一的方法实现下列功能:
     o 对现有资源的注释(Annotation of existing resources);
     o 向电子公告栏、新闻组,邮件列表或类似讨论组发送消息;
     o 提交数据块,如将表格(form [3])的结果提交给数据处理过程;
     o 通过附加操作来扩展数据库。
POST方法的实际功能由服务器来决定,而且通常依赖于请求URI。在POST过程中,
实体是URI的从属部分,就好象文件从属于包含它的目录、新闻组文件从属于发出
该文件的新闻组、记录从属于其所在的数据库一样。
成功的POST不需要在原始服务器创建实体,并将其做为资源;也不需要为未来的
访问提供条件。也就是说,POST方法不一定会指向URI指定的资源。在这种情况下,
200(成功)或204(无内容)都是适当的回应状态,取决于实际回应实体中对结
果的描述。
如果在原始服务器上创建了资源,回应应是201(已创建),并包含一个实体
(对"text/html"类型最为适合),该实体中记录着对新资源请求的状态描述。
在所有的HTTP/1.0的POST请求中,必须指定合法的内容长度(Content-Length)。
如果HTTP/1.0服务器在接收到请求消息内容时无法确定其长度,就会返回400(非
法请求)代码。
应用程序不能缓存对POST请求的回应,因为做为应用程序来说,它们没有办法知道
服务器在未来的请求中将如何回应。




附件二:
WWW FAQs: What is the maximum length of a URL?
[参考4]
2006-10-13: Although the specification of the HTTP protocol does not specify any maximum length, practical limits are imposed by web browser and server software.
Microsoft Internet Explorer (Browser)
Microsoft states that the maximum length of a URL in Internet Explorer is 2,083 characters, with no more than 2,048 characters in the path portion of the URL. In my tests, attempts to use URLs longer than this produced a clear error message in Internet Explorer.
Firefox (Browser)
After 65,536 characters, the location bar no longer displays the URL in Windows Firefox 1.5.x. However, longer URLs will work. I stopped testing after 100,000 characters.
Safari (Browser)
At least 80,000 characters will work. I stopped testing after 80,000 characters.
Opera (Browser)
At least 190,000 characters will work. I stopped testing after 190,000 characters. Opera 9 for Windows continued to display a fully editable, copyable and pasteable URL in the location bar even at 190,000 characters.
Apache (Server)
My early attempts to measure the maximum URL length in web browsers bumped into a server URL length limit of approximately 4,000 characters, after which Apache produces a "413 Entity Too Large" error. I used the current up to date Apache build found in Red Hat Enterprise Linux 4. The official Apache documentation only mentions an 8,192-byte limit on an individual field in a request.
Microsoft Internet Information Server
The default limit is 16,384 characters (yes, Microsoft's web server accepts longer URLs than Microsoft's web browser). This is configurable.
Perl HTTP::Daemon (Server)
Up to 8,000 bytes will work. Those constructing web application servers with Perl's HTTP::Daemon module will encounter a 16,384 byte limit on the combined size of all HTTP request headers. This does not include POST-method form data, file uploads, etc., but it does include the URL. In practice this resulted in a 413 error when a URL was significantly longer than 8,000 characters. This limitation can be easily removed. Look for all occurrences of 16x1024 in Daemon.pm and replace them with a larger value. Of course, this does increase your exposure to denial of service attacks.
Recommendations
Extremely long URLs are usually a mistake. URLs over 2,000 characters will not work in the most popular web browser. Don't use them if you intend your site to work for the majority of Internet users.
When you wish to submit a form containing many fields, which would otherwise produce a very long URL, the standard solution is to use the POST method rather than the GET method:
<form action="myscript.php" method="POST">
...
</form>
The form fields are then transmitted as part of the HTTP transaction header, not as part of the URL, and are not subject to the URL length limit. Short-lived information should not be stored in URLs.
As a rule of thumb, if a piece of information isn't needed to regenerate the same page as a result of returning to a favorite or bookmark, then it doesn't belong in the URL.
The Bookmark Problem
In very rare cases, it may be useful to keep a large amount of "state" information in a URL. For instance, users of a map-navigating website might wish to add the currently displayed map to their "bookmarks" or "favorites" list and return later. If you must do this and your URLs are approaching 2,000 characters in length, keep your representation of the information as compact as you can, squeezing out as much "air" as possible. If your field names take up too much space, use a fixed field order instead. Squeeze out any field that doesn't really need to be bookmarked. And avoid large decimal numbers - use only as much accuracy as you must, and consider a base-64 representation using letters and digits (I didn't say this was easy).
In extreme cases, consider using the gzip algorithm to compress your pretty but excessively long URL. Then reencode that binary data in base64 using only characters that are legal in URLs. This can yield a 3-4x space gain, at the cost of some CPU time when you unzip the URL again on the next visit. Again, I never said it was easy!
An alternative is to store the state information in a file or a database. Then you can store only the identifier needed to look up that information again in the URL. The disadvantage here is that you will have many state files or database records. Some of which might be linked to on websites run by others. One solution to this problem is to delete the state files or database records for the URLs that have not been revisited after a certain amount of time.
"What happens if the URL is too long for the server?"
What exactly happens if a browser that supports very long URLs (such as Firefox) submits a long URL to a web server that does not support very long URLs (such as a standard build of Apache)?
The answer: nothing dramatic. Apache responds with a "413 Entity Too Large" error, and the request fails.
This response is preferable to cutting the URL short, because the results of cutting the URL short are unpredictable. What would that mean to the web application? It varies. So it's better for the request to fail.
In the bad old days, some web servers and web browsers failed to truncate or ignore long URLs, resulting in dangerous "buffer overflow" situations. These could be used to insert executable code where it didn't belong... resulting in a security hole that could be exploited to do bad things.
These days, the major browsers and servers are secure against such obvious attacks - although more subtle security flaws are often discovered (and, usually, promptly fixed).
While it's true that modern servers are themselves well-secured against long URLs, there are still badly written CGI programs out there. Those who write CGI programs in C and other low-level languages must take responsibility for paying close attention to potential buffer overflows. The CGIC library can help with this.
In any case, if you're a web developer and you're still asking this question, then you probably haven't paid attention to my advice about how to avoid the problem completely.

参考文献:
[1] 表单Post&Get两个长度限制问题的分析[N] http://phoubes.bokee.com/5488853.html
[2] David Flanagan. Javascript权威指南【第五版】[m].北京:机械工业出版社,2007.8
[3] Maximum URL length is 2,083 characters in Internet Explorer[N] http://support.microsoft.com/kb/q208427/
[4] WWW FAQs: What is the maximum length of a URL? [N] http://www.boutell.com/newfaq/misc/urllength.html
[5] HTTP/1.1: Method Definitions[N] http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3
[6] HTTP协议中的GET和POST[N] http://www.cnblogs.com/westsourcer/archive/2008/06/12/702521.html