本文从如下几个方面走进 GET 与 POST 的区别:前端
GET 与 POST 是 HTTP 请求中最经常使用的两种方法,GET 与 POST 的区别也是老生常谈的问题了,信手拈来git
GET | POST | |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被从新提交(浏览器应该告知用户数据会被从新提交)。 |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 能被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。 |
历史 | 参数保留在浏览器历史中。 | 参数不会保存在浏览器历史中。 |
对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 | 无限制。 |
对数据类型的限制 | 只容许 ASCII 字符。 | 没有限制。也容许二进制数据。 |
安全性 | 与 POST 相比,GET 的安全性较差,由于所发送的数据是 URL 的一部分。在发送密码或其余敏感信息时毫不要使用 GET ! | POST 比 GET 更安全,由于参数不会被保存在浏览器历史或 web 服务器日志中。 |
可见性 | 数据在 URL 中对全部人都是可见的。 | 数据不会显示在 URL 中。 |
上面是 w3school 给出的标准答案github
但你真的理解它吗?在咱们学习了那么多 HTTP 知识后,仅仅回答这些就够了吗?GET 与 POST 都是 HTTP 的请求方法,如何理解请求方法?本质区别又是什么?web
下面让咱们一步步走进 GET 与 POST 方法,以及二者的本质区别面试
HTTP (HyperText Transfer Protocol)是创建在 TCP 上的应用层协议,超文本传输协议。其中:算法
因此,HTTP 协议用更通俗易懂的话描述就是 一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范跨域
虽然说 HTTP 协议是“传输协议”,但它不关心寻址、路由、数据完整性等传输细节,这些底层的具体传输工做是由 TCP/IP 协议负责,例如 IP 协议实现寻址和路由、TCP 协议实现可靠数据传输,另外还有 DNS 协议实现域名查找、SSL/TLS 协议实现安全通讯等浏览器
那 HTTP 协议主要干吗喃?缓存
HTTP 协议的核心部分就是它定义的传输报文的格式,例如报文的组成、解析规则等,以便于在 TCP/IP 上实现更多样灵活的功能,如缓存控制、数据编码、内容协议等安全
HTTP 报文分为四部分:
注意:此报文中最后是一个空白行结束,没有 body(GET 请求通常都没有 body)
其中,请求方法就规定在起始行中:
客户端发起 HTTP 请求,服务器响应客户端请求,客户端能够对服务器端的资源进行操做,例如查询、添加、删除等,但具体执行哪一种操做喃?
这就是请求方法存在的意义,它规定了客户端的某种操做指令,用来告诉服务器端我须要进行哪一种操做,常见的请求方法有:
GET 请求方法应该是 HTTP 全部请求方法中最开始出现的了,它表示从服务器获取资源
POST 请求方法是 HTTP 全部协议中除 GET 以外最常使用的请求方法了,它表示向指定的服务器资源提交数据,提交数据存放在 HTTP 报文中的 body 中,一般致使状态或服务器上的反作用的更改
综上所述,总结一下,GET 与 POST 的本质区别有两点:
在 HTTP 协议里,所谓的“安全”是指请求方法不会对服务器上的资源进行修改,“破坏”服务器上的资源
按照这种定义,GET 请求方法是安全的,它对服务器资源执行的仅仅是只读操做,也是幂等的
幂等指屡次执行相同的操做,结果也都是相同的,即屡次“幂”后结果“相等”
POST 请求方法是不安全的,它会修改服务器上的资源,在 RFC 里的语义,POST 是指“新增或提交数据”,屡次提交数据会建立多个资源,因此不是幂等的
总结:
对于传输来讲,GET 和 POST 报文在传输上都是不安全的,由于 HTTP 在网络上是明文传输的,想要安全传输就得加密,也就是 HTTPS
这个就神奇了,在部分文章中提到,POST 请求方法会将 header 和 body 分开发送,先发送 header,服务端返回 100 状态码再发送 body 🤔️🤔️🤔️
HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,并且实际测试(Chrome、Firefox)发现,header 和 body 不会分开发送。
但为何有些做者会这样写喃?我查找了相关资料,终于发现,真有这种状况,原文在这里:
In search of performance - how we shaved 200ms off every POST request
主要内容是做者发现 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 就不会有响应
所以,大多数框架都是尽可能在一个 TCP 包里面把 HTTP 请求发出去的,可是也确实存在先发 HTTP 头,而后发 body 的框架。可是具体发多少个TCP包,这个 不是 HTTP 协议的事情是操做系统 TCP 协议栈与代码的问题,跟 HTTP 不要紧