amandakelake/blog

GET和POST:辩证看100 continue,以及最根本区别

amandakelake opened this issue · 0 comments

之前看了这一篇文章
99%的人都理解错了HTTP中GET与POST的区别
得出了两个简明意赅的结论,一度也以为自己把握了get和post的精髓

GET产生一个TCP数据包;POST产生两个TCP数据包。

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

后来又看到了一篇怼上一篇文章的文章
听说『99% 的人都理解错了 HTTP 中 GET 与 POST 的区别』??
文章对原文的结论提出了一些疑问

主要关于首部Expect: 100-continue的区别
赶紧回去翻了下《HTTP权威指南》寻找官方解释,第62页和附录C的解释

100 Continue的目的是对HTTP客户端应用程序有一个实体的主体部分要发送服务器,但希望在发送之前查看一下服务器是否会接受这个实体这种情况进行优化

客户端

如果客户端在向服务器发送一个实体,并愿意在发送实体之前等待100 Continue响应,那么客户端就要发送一个携带了值为100 Continue的Expect请求首部。如果客户端没有发送实体,就不应该发送100 Continue Expect首部,因为这样会使服务器误以为客户端要发送一个实体

认真看这个地方,就会发现跟第一篇文章中的区别,这里是客户端愿意发100 continue才会有响应,并不是每次都会有100 continue响应,再对比下第一篇文章的结论

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

区别就在这里

服务器端

如果服务器收到一条带有值为100 Continue的Expect首部的请求,它会用100 Continue响应或一条错误码来进行响应。服务器永远也不应该向没有发送100 Continue期望的客户端发送100 Continue状态码
如果服务器在有机会发送100 Continue响应之前就收到了部分(或者全部)的实体,说明服务器已经打算继续发送数据了,这样服务器就不需要发送这个状态码了,但是服务器完成请求之后,还是应该为请求发送一个最终状态码
看到了吗,没收到客户端的100 Continue就不会有响应

第二篇文章中得出的结论是

通过抓包发现,尽管会分两次,body 就是紧随在 header 后面发送的,根本不存在『等待服务器响应』这一说

其实,从理论上来说,这些知识最好都应该自己去实践去查阅RFC文档,辩证看待前人作者的结论,就像我们怀疑了第一篇文章的结论,那凭什么不能继续怀疑第二篇文章的结论呢,那当然是应该的!有兴趣深入的可以继续怀疑《HTTP权威指南》

首先掰正了一个100 continue概念,
然后再根据一些目前大家都认可的答案去辩证看一下

这里是w3c的对比 HTTP 方法:GET 对比 POST
ba785da2-bb4d-4155-b847-d20343f9542f

首先,GET和POST是由HTTP协议定义的,Method和Data(URL, Body, Header)这两个概念没有必然的联系,使用哪个Method与应用层的数据如何传输是没有相互关系的

HTTP没有要求,如果Method是POST数据就要放在BODY中。也没有要求,如果Method是GET,数据(参数)就一定要放在URL中而不能放在BODY中

HTTP协议明确地指出了,HTTP头和Body都没有长度的要求,URL长度上的限制主要是由服务器或者浏览器造成的

到目前为止,纠正了几个概念,到最后,问起来,get和post的最核心区别是什么?我可能会回答:
在用法上,一个用于获取数据,一个用于修改数据;
在根本上,没有啥区别
在细节上,有一些区别,需要展开讲嘛?

既然说到HTTP请求了,那自然就要聊一下TCP,请看下一篇