HTTP 协议中 GET 和 POST 方法详解
GET请求报文分析
1、请求行
请求方法
GET(描述该请求采用了什么请求方法),HTTP 1.0 和 1.1 协议中共包含10种请求方法。不过 HTTP 1.1 中只有8种方法。
URI
请求WEB服务器的资源名称。
URI:统一资源标识符(代表这个资源的名称),如:上图中的 /PrjTheHttpProtocol/test?username=admin&userpassword=123
说明:HTTP协议规定GET请求发送数据在URI中发送,格式:uri?name=value&name=value&name=value…..
URL:统一资源定位符(不但代表这个资源的名称,而且通过它还可以找到该资源),如:http://ip:port/URI
协议版本
HTTP 1.1(当前使用的HTTP协议版本)
2、请求报头
告诉web服务器浏览器接收的语言版本。
请求web服务器的IP地址和端口号。
Cookies等信息。
3、空白行
分割请求报头和请求体的专用行。
4、请求体
由于当前使用的请求方式是GET请求方式,所以请求体中不传送任何数据。
POST请求报文分析
1、 请求行
与GET方法一样,请求行也包括请求方法、URI、协议版本。
不同的是采用POST方式发送请求,URI后边没有任何数据。
2、 请求报头
由于请求是POST请求,所以报头中显示:Cache-Control:no-cache
3、 空白行
分割请求报头和请求体的专用行。
4、 请求体
由于当前使用的请求方式是POST请求方式,所以数据在请求体中发送,并且默认格式是:name=value&name=value&name=value……
当然,可以通过在请求报头里指定 Content-Type 来指定为其他格式。
响应报文分析
1、 状态行
协议版本
HTTP 1.1:HTTP协议版本号
状态码
200:响应状态号
OK:对响应结果的描述
2、 响应报头
WEB服务器版本信息
内容类型以及字符编码方式
内容长度,响应回来的总字符数
响应时间
Cookies等信息
3、 空白行
分割响应报头和响应体的专用行。
4、 响应体
响应正文
GET和POST的区别
1、 一次HTTP请求中 POST 两次发包,GET 一次发包。
多数浏览器对于POST采用两阶段发送数据的,先发送请求头,再发送请求体,即使参数再少再短,也会被分成两个步骤来发送(相对于GET),也就是第一步发送 head 数据,第二步再发送 body 部分。HTTP 是应用层的协议,而在传输层有些情况 TCP 会出现两次连结的过程,HTTP 协议本身不保存状态信息,一次请求一次响应。对于 TCP 而言,通信次数越多可靠性越低,能在一次连结中传输完需要的消息是最可靠的,尽量使用 GET 请求来减少网络耗时。如果通信时间增加,这段时间客户端与服务器端一直保持连接状态,在服务器侧负载可能会增加,可靠性会下降。
2、GET请求的结果能够被缓存,POST的请求结果不进行缓存。
GET 请求返回结果能够被保存在浏览器的浏览历史里面,如果密码等重要数据使用 GET 提交,别人查看历史记录,就可以直接看到这些私密数据。
3、GET请求和POST请求的参数携带位置不同。
GET请求通过URL(请求行)提交数据,在URL中可以看到所传参数。POST通过“请求体”传递数据,参数不会在URL中显示 。
4、GET请求提交的数据一般都有长度限制,POST请求一般没有限制。
(1)GET方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。下面就是对各种浏览器和服务器的最大处理能力做一些说明。
浏览器/服务器 | 说明 |
---|---|
Microsoft Internet Explorer(IE) | URL最大长度限制为2083个字符,如果超过这个数字,提交按钮没有任何反应。 |
FireFox | URL最大长度限制为65,536个字符 |
Safari | URL最大长度限制为 80,000个字符 |
Opera | URL最大长度限制为190,000个字符 |
Google Chrome | URL最大长度限制为8182个字符 |
Apache Server | 服务器,能接受最大URL长度为8,192个字符 |
Microsoft Internet Information Server(IIS) |
服务器,能接受最大URL长度为16,384个字符 |
通过上面的数据可知,为了让所有的用户都能正常浏览, URL最好不要超过IE的最大长度限制(2083个字符),当然,如果URL不直接提供给用户(浏览器),而是提供给程序调用,这时的长度就只受Web服务器影响了。
注意:对于中文的传递,最终会为urlencode后的编码形式进行传递,如果浏览器的编码为UTF8的话,一个汉字最终编码后的字符长度为9个字符。
(2)理论上讲,POST是没有大小限制的。HTTP协议规范也没有进行大小限制,起限制作用的是服务器的处理程序的处理能力。
如:在Tomcat下取消POST大小的限制(Tomcat默认2M)。打开 Tomcat 目录下的 conf 目录,打开server.xml 文件,增加 maxPostSize="0"(设为0是取消POST的大小限制)
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" maxPostSize="0" />
GET和POST使用上的一些问题
对于HTTP协议下的GET请求参数长度是有大小限制的,最大不能超过XX,而 POST 是无限制?
(1)首先即使有长度限制,也是限制的是整个 URI 长度,而不仅仅是你的参数值数据长度。
(2)HTTP 协议从未规定 GET/POST 的请求长度限制是多少。
(3)所谓的请求长度限制是由浏览器和 Web 服务器决定和设置的,各种浏览器和 Web 服务器的设定均不一样,这依赖于各个浏览器厂家的规定或者可以根据 Web 服务器的处理能力来设定。
HTTP请求的两种方式,GET和POST请求的本质上的区别:
HTTP协议是这样解释GET和POST的:GET请求不应该做读取数据之外的事情。而如果一个请求,修改了服务器资源或者使用了服务器资源(如发邮件,使用打印机等),那么应当使用POST。所以,GET和POST的本质区别是使用场景的区别,简单的说,GET是只读,POST是写。浏览器对两种请求的不同处理方式也是基于这两个不同的场景:
GET:查询往往需要的上传的数据量比较小,查询参数也往往不需要保密,所以放在URL里比较高效。HTTP协议要求同一URL的多个请求应该返回同样的结果,所以浏览器可以把返回结果缓存起来,以提高性能。至于参数长度的限制,这个是和浏览器URL的长度限制相关的,1024也好,2048也好,其实没有太大的意义,参数超长往往是错误使用GET方法的结果。
POST:修改数据需要支持大数据量表单的提交,数据也常常包含用户的私人信息,所以数据放在请求的消息体中传递。相同的POST请求可能会对服务器端产生不同的影响,比如两次POST可能创建两条不同的数据,所以对POST返回结果的缓存是没有意义的。
如何判断当前请求是GET请求还是POST请求?
(1)在浏览器地址栏上直接编写URL提交的请求一定是GET请求。
(2)使用热链接向服务器发送的请求一定是GET请求。
(3)使用form表单提交数据的时候,如果method属性没有编写,或者method属性值被指定是GET,这样发送的请求属于GET请求。
(4)使用form表单提交数据的时候,如果method属性值被手动指定为POST,那么该请求属于POST请求。
用GET,还是用POST?
如果回答“因为POST的参数长度不受限制,所以我用POST,就有点本末倒置了。两者之间如何选择,首先要看是不是修改或者使用了服务器资源,其次要看请求或者响应中的数据是不是包含了敏感信息,如果是,那么应该选择POST,同时处于安全性的考虑,服务器端应该只接受POST,拒绝GET。比如数据的增加和修改,认证信息的提交,是一定要用POST的。如果只是简单查询,用GET就可以了。
POST请求是不是比GET请求更安全?
有人说“POST比GET安全,因为GET的参数都明文写在URL上了”,从个人信息安全的角度上说,这句话是对的,但这种安全机制是“防君子不防小人”的,有各种工具能够获取POST请求的数据。如前面所说,两者有截然不同的使用场景,如果是该用POST的地方用了GET,又说GET不安全,那GET也太冤枉了。其实,HTTP协议中提到GET是安全的方法(safe method),其意思是说GET方法不会改变服务器端数据,所以不会产生副作用。这是建立在Web开发人员正确使用GET方法的基础上的,如果修改数据的请求却使用了GET方法,显然是非常危险的。
GET与POST的误用有什么危害?
应该使用GET的地方用了POST:性能受损,浏览器不会缓存。
应该使用POST的地方用了GET:每一个这样的地方都是一个漏洞,有可能被黑客利用。如果是一个对安全要求很高的网站,一定不要忽视。
不仅仅是在前端要正确的使用GET和POST,同时还需要后端代码的支持,比如后端应当在需要POST请求的时候拒绝GET请求,从而切断黑客利用GET请求攻击的途径,更高级别的,还需要对POST请求进行过滤,以确保所有的POST请求都来自可信任的地址。