HTTP中的GET和POST方法详解

一般来说GET是获取数据,POST是提交数据的。但是因为GET和POST都是HTTP的方法,HTTP又是基于TCP/IP的关于数据在万维网中如何让通讯的协议。从本质上讲,GET和POST都是HTTP请求,都是TCP链接,是无区别的。

但是HTTP协议既然有了这两个方法,就是为了在特定的情况下区分应用。

1、GET是获取数据,POST是提交数据的。
GET方法通常用于请求服务器发送某个资源,而且应该是安全的和幂等的。
仅仅是获取资源信息,就像数据库查询一样,不会修改和增加数据,不会影响资源的状态。

POST方法向服务器提交数据,将数据提交给服务器处理。POST是向服务器传输数据,数据会被重新提交,所以就会有对原有的数据造成伤害。向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。

安全的和幂等的。所谓安全的意味着该操作用于获取信息而非修改信息。幂等的意味着对同一个 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。换句话说,GET 请求一般不应产生副作用。从根本上讲,其目标是当用户打开一个链接时,可以确信从自身的角度来看没有改变资源。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。反之亦然。POST 请求就不那么轻松了。POST 表示可能改变服务器上的资源的请求。仍然以新闻站点为例,读者对文章的点赞应该通过 POST 请求实现,因为在点赞提交之后站点已经不同了,点赞数增多了。

2、考虑参数的位置:GET请求的参数位于url中,而POST请求的参数位于request body中。
这导致了三个问题,
一是GET请求的安全性不如POST请求;
二是GET的参数有长度限制,而POST没有;
三是GET的参数只允许ASCII字符,POST没有限制。

GET方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在Request Body内提交。使用 GET的时候,参数会显示在地址栏上,而 POST不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 GET;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 POST为好。

HTTP协议并没有对GET和POST的长度做限制,GET的最大长度限制是因为浏览器和web服务器限制了URL的长度
URL地址是有长度限制的(GET方式在通过URL提交数据),浏览器不同长度限制的具体数值也是不一样的。比如IE是2083字节。需要注意的是这些仅仅是URL地址栏的长度限制。
理论上来说POST的长度是没有限制的(POST方式,数据放置在Request body内提交),但是受服务器的配置限制或者内存大小的限制,造成了实际开发中POST也是有数据长度的限制的。

3、为什么GET比POST更快
1.POST请求包含更多的请求头
因为POST需要在请求的body部分包含数据,所以会多了几个数据描述部分的首部字段(如:content-type),这其实是微乎其微的。

2.最重要的一条,POST在真正接收数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据
POST请求的过程:
(1)浏览器请求tcp连接(第一次握手)
(2)服务器答应进行tcp连接(第二次握手)
(3)浏览器确认,并发送post请求头(第三次握手)
(4)服务器返回100 Continue响应
(5)浏览器发送数据

(6)服务器返回200 OK响应
GET请求的过程:
(1)浏览器请求tcp连接(第一次握手)
(2)服务器答应进行tcp连接(第二次握手)
(3)浏览器确认,并发送get请求头和数据(第三次握手)
(4)服务器返回200 OK响应

因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?

1) GET与POST都有自己的语义,不能随便混用。
2) 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
3)并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

3.GET会将数据缓存起来,而POST不会 (GET在浏览器回退时是无害的,而POST会再次提交请求。GET会将请求参数放在请求的url中,回退操作实际上浏览器会从之前的缓存中拿结果;POST每次调用都会创建新的资源。)

可以做个简短的测试,使用ajax采用GET方式请求静态数据(比如html页面,图片)的时候,如果两次传输的数据相同,第二次以后消耗的时间将会在10ms以内(chrome测试),而POST每次消耗的时间都差不多。经测试,chrome和firefox下如果检测到GET请求的是静态资源,则会缓存,如果是数据,则不会缓存,但是IE什么都会缓存起来。

4.POST不能进行管道化传输
使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销。为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或HTTP connection reuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。

但是这样的方式有一个问题:不安全,如果一个管道中有10个连接,在发送出9个后,突然服务器告诉你,连接关闭了,此时客户端即使收到了前9个请求的答复,也会将这9个请求的内容清空,也就是说,白忙活了……此时,客户端的这9个请求需要重新发送。这对于幂等请求还好(比如GET,多发送几次都没关系,每次都是相同的结果),如果是POST这样的非幂等请求,肯定是行不通的。
所以,POST请求不能通过管道的方式进行通信!很有可能,POST请求需要重新建立连接,这个过程不跟完全没优化的时候一样了么?所以,在可以使用GET请求通信的时候,不要使用POST请求,这样用户体验会更好,当然,如果有安全性要求的话,POST会更好。管道化传输在浏览器端的实现还需考证,貌似默认情况下大部分浏览器(除了opera)是不进行管道化传输的,除非手动开启!
总结:

GET POST
参数位置 url中 Request Body中
参数长度 有限制 无限制
参数编码 ASCII编码 无限制
后退/刷新 不重复提交,回退无害 重复提交,回退有害
安全性 参数暴露,不安全 安全
缓存 可以缓存 不可以缓存
书签 可以收藏为书签 不可以收藏为书签
历史 参数保存在浏览器历史 不保存在浏览器历史
请求包个数 1个 http header+data 2个 先 http header ,再data

根据这个总结你可以大胆放心的展开说了!

参考了很多博客还有自己理解添加整理,希望过些日子如果面试被问到会有帮助,也希望看到这篇博客的人天天开心。欢迎指正。

参考链接 :http://www.blogjava.net/honeybee/articles/164008.html
https://zhuanlan.zhihu.com/p/22536382
https://blog.csdn.net/cuiwkong/article/details/90312283
https://blog.csdn.net/zzk220106/article/details/78595108/

你可能感兴趣的:(http,POST,GET)