不要问我封面为什么是小猪佩奇,问就是我电脑上只有这一张图片。
日常开发过程中,get/post请求是不可避免的操作,那他们两个之间有什么区别的?这是老生常谈的问题了,今天有时间整理一下,来具体看看吧。
1、首先来看看W3c(HTTP 方法:GET 对比 POST_w3cschool)给出的二者区别:
下面的表格比较了两种 HTTP 方法:GET 和 POST。
GET | POST | |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 能被缓存(会被浏览器主动缓存) | 不能缓存(可以手动设置) |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded or multipart/form-data。为二进制数据使用多重编码。 |
历史 | 参数保留在浏览器历史中。 | 参数不会保存在浏览器历史中。 |
对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 | 无限制。 |
对数据类型的限制 | 只允许 ASCII 字符。 | 没有限制。也允许二进制数据。 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。 在发送密码或其他敏感信息时绝不要使用 GET ! | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 |
可见性 | 数据在 URL 中对所有人都是可见的。 | 数据不会显示在 URL 中。 |
参考:GET和POST两种基本请求方法的区别 - 在途中# - 博客园
参考:你真的了解 GET 和 POST 吗,它们的区别是什么?
2、刚接触前端那会儿,知道面试官经常问的一个点是get与post的区别。就像高考中的必考题一样,这个问题也伴随了我很久。那个时候只是单纯地背二者的区别,比如post请求更安全,因为get请求中的传参会带着url中,暴露在外面,真的是这样子吗?;比如get请求对数据的长度是有限制的,而post请求没有限制,记得有个面试官问我发送文件用什么请求,长度限制?接下来具体看看二者的区别,再有人问起,该怎么回答?
3、深入学习GET与POST请求
(1)GET表示从服务器获取资源;POST表示向指定的服务器资源提交数据(通常导致状态或服务器上的副作用更改);
(2)关于他们是否安全,之前的回答,是正确的吗?应该说是不够严谨。
在HTTP协议中,所谓的“安全”是指请求方法不会对服务器上的资源进行修改,“破坏”服务器上的资源。按照这种定义的话,GET请求方法是安全的,它对服务器资源执行的仅仅是只读操作,也是幂等的。
幂等指多次执行相同的操作,结果也都是相同的,几多次“幂”后结果“相等”。
POST 请求方法是不安全的,它会修改服务器上的资源,在 RFC 里的语义,POST 是指“新增或提交数据”,多次提交数据会创建多个资源,所以不是幂等的。
小结1:GET安全,幂等;POST不安全,不幂等。
对于传输来说,GET 和 POST 报文在传输上都是不安全的,因为 HTTP 在网络上是明文传输的,想要安全传输就得加密,也就是 HTTPS。
(3)后来我看到过一篇文章,提到post会发送两个请求,会将header和body分开发送,先发送header,返回100的状态码,再发送body,会返回200。那时也是记忆为主,今天来看看具体是怎么回事吧。
HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome、Firefox)发现,header 和 body 不会分开发送。
在一篇帖子中,作者这样介绍,实际我是没有看到作者提到的文章的。
主要内容是作者发现 POST 比 GET 多 200ms,然后深入研究,发现 ruby 的 net::HTTP 库,会将一个 http 请求拆分,先发送 header 部分。另外,由于没有设置 TCP_NODELY ,所以第一个包之后要等待 ack ,才发下一个包,导致了一个请求有 200ms 的延迟。
另外,关于 HTTP 100 Continue:
100 Continue的目的是对HTTP客户端应用程序有一个实体的主体部分要发送服务器,但希望在发送之前查看一下服务器是否会接受这个实体这种情况进行优化
----《HTTP权威指南》
客户端:
如果客户端在向服务器发送一个实体,并愿意在发送实体之前等待100 Continue响应,那么客户端就要发送一个携带了值为100 Continue的Expect请求首部。如果客户端没有发送实体,就不应该发送100 Continue Expect首部,因为这样会使服务器误以为客户端要发送一个实体
服务器端:
如果服务器收到一条带有值为100 Continue的Expect首部的请求,它会用100 Continue响应或一条错误码来进行响应。服务器永远也不应该向没有发送100 Continue期望的客户端发送100 Continue状态码。
如果服务器在有机会发送100 Continue响应之前就收到了部分(或者全部)的实体,说明服务器已经打算继续发送数据了,这样服务器就不需要发送这个状态码了,但是服务器完成请求之后,还是应该为请求发送一个最终状态码
也就是说,没收到客户端的 100 Continue 就不会有响应。
小结2:大锁疏忽框架都是尽量在一个TCP包里面把HTTP请求发出去的,但是也确实存在先发HTTP头,然后发送body的框架。但是具体发多少个TCP包,这不是HTTP协议的事情,是错做系统TCP协议栈与代码的问题,跟HTTP没关系。
该部分内容来源:你真的了解 GET 和 POST 吗,它们的区别是什么?
(4)GET在浏览器回退时是无害的,而post会再次提交请求。