作者:Gakki
我们先来看看 w3school 中对于 GET 与 POST 的解释。 GET 与 POST 的区别
分类 | GET | POST | 对比 |
---|---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交) | 每次都重新提交这无疑会对浏览器造成压力,该问题也是作为 web 端性能优化的重要方向之一 |
书签 | 可收藏为书签 | 不可收藏为书签 | |
缓存 | 能被缓存 | 不能缓存 | 缓存可以为浏览器减少请求链数,web 端性能优化的重要方向之一 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码 | |
历史 | 参数保留在浏览器历史中 | 参数不会保存在浏览器历史中 | 相当于缓存,可减少浏览器压力 |
对数据长度的限制 | 当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符) | 无限制 | HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原因;服务器是因为处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制 |
对数据类型的限制 | 只允许 ASCII 字符 | 没有限制。也允许二进制数据 | POST 选择更多 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分 | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中 | 从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,浏览器F12下什么都一目了然,或者抓个包,就能完整地获取数据报文 ;要想安全传输,Encode(转码)当然对于懂的人来说也不安全; 比较安全的只有加密,也就是 HTTPS |
可见性 | 数据在 URL 中对所有人都是可见的 | 数据不会显示在 URL 中 |
- 注:上述区别在大部分浏览器上是存在的,因为这些浏览器实现了 HTTP 标准
- 所以,从上述标准来看,GET 与 POST 的区别在于:
- GET 用于获取信息,是无副作用的,是幂等的且可缓存
- POST 用于修改服务器上的数据,有副作用,非幂等,不可缓存
- 注,幂等的概念:如果一个操作没有副作用,或者多次操作对资源产生的副作用相同,我们就说这个操作是幂等的
1. GET 与 POST
-
一般在面试的时候,面试官都会问道这个问题,一般这样回答:
- GET 在浏览器回退时是无害的,而 POST 会再次提交请求
- GET 参数通过 URL 传递,POST 放在 body 中
- GET 比 POST 更不安全,因为 GET 请求的时候将参数直接暴露在 URL 上,所以最好不要用来传递敏感信息
- 对比参数的数据类型,GET 只接受 ASCII 字符,而 POST 没有限制
- GET 请求只能进行 URL 编码,而 POST 支持多种多种编码方式
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET 常用于获取数据,POST 用于提交数据
但其实,GET 与 POST 并没有实质的区别
POST 与 GET 是什么?它们都是 HTTP 协议中的两种发送请求的方法
那什么是 HTTP 了? HTTP 超文本传输协议(Hypertext Transfer Protocol,缩写 HTTP)旨在启用客户端和服务器之间的通信。HTTP 充当客户端和服务器之间的请求-响应协议。如:客户端(浏览器)向服务器发送 HTTP 请求;然后服务器将响应返回客户端。响应包含有关请求的状态信息,也可能包含所请求的内容。HTTP 的底层是 TCP/IP ,因此 GET 和 POST 的底层也是 TCP/IP 。换句话说,GET 和 POST 都是 TCP 链接,你可以给 GET 的 request body 中传值,也可以给 POST 加上 URL 参数,只是看服务器那边是否接受处理。导致 GET 与 POST 在应用中区别的是由于 HTTP 的规定和浏览器/服务器的限制
TCP 是用来传输数据的,是可靠传输。HTTP 规定了几种常用的请求方法,最常用的POST 、 GET ,HTTP 规定在 GET 请求的时候,要求把传送的数据放在 URL 中,POST 请求的时候,放在 body 中。但是,你也可以在 GET 请求的时候,在 body 中放参数,POST 请求的时候,在 URL 放数据。HTTP 只是一个准则,主要的还是需要看 TCP
关于 w3school 所说的参数大小的限制是在哪体现的了?理论上,你可以在 URL 中无限制的加参数,但是浏览器与服务器会去限制单次传输的参数来控制风险,数据量太大会对浏览器与服务器造成很大的风险。因此,在万维网(WWW)中,大多数的浏览器通常都会限制 URL 长度在 2K 个字节,而大多数服务器最多也只处理 64K 大小的 URL ,超过的部分都不会去处理。但如果用 GET 请求的时候,在 request body 中放了数据,不同的服务器处理的方式也不同,有的会处理,有的服务器会直接忽略。因此,虽然 GET 可以在 body 放参数,但也不能保证服务器会接收数据
因此,GET 与 POST 本质上都是 TCP 链接,没有什么差别。但是由于 HTTP 的规定 与 浏览器/服务器 的限制,导致 GET 与 POST 在应用中存在区别
2. GET 与 POST 实质的区别
- GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包
- 对于 GET 请求,浏览器会把 header 和 data 一起发送出去,服务器会响应数据
- 而对于 POST 请求,浏览器会先将 header ,服务器响应 100 状态码,接着浏览器再将 data 数据发送出去,服务器响应数据
- 总结,GET 只需要发送一次包,而 POST 会发送给两次包。因为 POST 需要发送两次的原因,导致会比 GET 更会费时间。但是在网络环境比较好的情况下,发一次包的时间和发两次包的时间基本没有差别;而在网络环境比较差的情况下,两次包的 TCP 在验证数据包的完整性上有着非常大的优势。然后就是并不是所有的浏览器都会在 POST 中发送两次包,FireFox 、Chrome 只会发送一次;header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 POST 必然行为。
3. 杂谈
POST 方法比 GET 方法安全?
- 按照网上大多数博文的回答,POST 都比 GET 安全,因为 POST 是将参数放在 body 中传输的,在 URL 中是不可见的。但是,从传输的角度来说,它们都是不安全的,因为 HTTP 在网络上是明文传输,只要在网络节点上进行抓包,就可以把数据完整的获取下来。要想安全传输,最好使用加密,也就是 HTTPS
- 关于 GET 方法的长度限制?
- 在 w3school 中,我们看到 URL 的长度是受限制的。但 HTTP 协议没有对 body 与 URL 的长度设置限制,对 URL 设置限制大多数都是浏览器和服务器的原因。当服务器处理较长的 URL 的时候,需要消耗比较多的资源,为了性能和安全考虑(防止恶意构置长 URL 来攻击服务器),会给 URL 长度加限制
为什么body更安全?
- 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET
- POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中
- 从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,浏览器F12下什么都一目了然,或者抓个包,就能完整地获取数据报文 ;要想安全传输, 比较安全的只有加密,也就是 HTTPS
get长度和浏览器有关?
- HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原因;服务器是因为处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制