HTTP 中 GET 请求和 POST 请求的区别(通俗易懂)

标准答案

我们先看一下 w3school 的标准答案

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 中。

从标准上来看,GET 和 POST 的区别如下:

  • GET 用于获取信息,是无副作用的,是幂等的,且可缓存
  • POST 用于修改服务器上的数据,有副作用,非幂等,不可缓存
     

我们从以下几个方面来具体看一下二者的区别
 

1. 作用

GET 用于获取资源,而 POST 用于传输实体主体。
 

2. 参数

GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出现在 URL 中,而 POST 的参数存储在实体主体中。不能因为 POST 参数存储在实体主体中就认为它的安全性更高,因为照样可以通过一些抓包工具(Fiddler)查看。

因为 URL 只支持 ASCII 码,因此 GET 的参数中如果存在中文等字符就需要先进行编码。例如 中文 会转换为 %E4%B8%AD%E6%96%87,而空格会转换为 %20。POST 参数支持标准字符集。

GET /test/demo_form.asp?name1=value1&name2=value2 HTTP/1.1
POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2

3. 安全

安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。

GET 方法是安全的,而 POST 却不是,因为 POST 的目的是传送实体主体内容,这个内容可能是用户上传的表单数据,上传成功之后,服务器可能把这个数据存储到数据库中,因此状态也就发生了改变。
 

4. 幂等性

幂等的 HTTP 方法,同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。

所有的安全方法也都是幂等的。

在正确实现的条件下,GET是幂等的,而 POST 方法不是。

GET /pageX HTTP/1.1 是幂等的,连续调用多次,客户端接收到的结果都是一样的:

GET /pageX HTTP/1.1
GET /pageX HTTP/1.1
GET /pageX HTTP/1.1
GET /pageX HTTP/1.1

POST /add_row HTTP/1.1 不是幂等的,如果调用多次,就会增加多行记录:

POST /add_row HTTP/1.1   -> Adds a 1nd row
POST /add_row HTTP/1.1   -> Adds a 2nd row
POST /add_row HTTP/1.1   -> Adds a 3rd row

5. 可缓存

如果要对响应进行缓存,需要满足以下条件:

  • 请求报文的 HTTP 方法本身是可缓存的, GET 是可缓存的,POST 在多数情况下不可缓存的。
  • 响应报文的状态码是可缓存的,包括:200, 203, 204, 206, 300, 301, 404, 405, 410, 414, and 501。
  • 响应报文的 Cache-Control 首部字段没有指定不进行缓存。
     

6. XMLHttpRequest

为了阐述 POST 和 GET 的另一个区别,需要先了解 XMLHttpRequest:

XMLHttpRequest 是一个 API,它为客户端提供了在客户端和服务器之间传输数据的功能。它提供了一个通过 URL 来获取数据的简单方式,并且不会使整个页面刷新。这使得网页只更新一部分页面而不会打扰到用户。XMLHttpRequest 在 AJAX 中被大量使用。

  • 在使用 XMLHttpRequest 的 POST 方法时,浏览器会先发送 Header 再发送 Data。但并不是所有浏览器会这么做,例如火狐就不会。
  • 而 GET 方法 Header 和 Data 会一起发送。
     

7. 补充

1. GET 方法参数写法是固定的吗?

在约定中,我们的参数是写在 ? 后面,用 & 分割。

我们知道,解析报文的过程是通过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。比如header请求头中添加token,来验证用户是否登录等权限问题。也就是说,我们可以自己约定参数的写法,只要服务端能够解释出来就行,万变不离其宗。

2. GET 方法的长度限制是怎么回事?

网络上都会提到浏览器地址栏输入的参数是有限的。

首先说明一点,HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原因。

浏览器原因就不说了,服务器是因为处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制。

3. POST 方法比 GET 方法安全?

有人说POST 比 GET 安全,因为数据在地址栏上不可见。

然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。

要想安全传输,就只有加密,也就是 HTTPS。

4. POST 方法会产生两个 TCP 数据包?

有些文章中提到,post 会将 header 和 body 分开发送,先发送 header,服务端返回 100 状态码再发送 body。

HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome)发现,header 和 body 不会分开发送。

所以,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为。
 

小结

最后的最后我们来做一个小结:

  1. GET 在浏览器回退是无害的,而 POST 会再次提交请求
  2. GET 产生的URL地址可以被网址收藏 BOOKMARK,而 POST 不可以
  3. GET 请求只能进行url编码,而 POST 支持多种编码形式
  4. GET 请求参数会被完整保留在浏览器历史记录里,而 POST 中的参数不会被保留
  5. GET 请求在URL中传递的参数是有长度限制的不超过4k,而 POST没有
  6. 对参数的数据类型,GET 只接受ASCII类型,而POST没有限制
  7. GET 比 POST 更不安全,因为参数直接暴露在URL上,所以不能用传递敏感信息
  8. GET 参数通过URL传递,POST 放在request body报文体中
  9. GET 产生一个TCP数据包,POST 产生两个TCP数据包

 
 
参考:

https://www.w3school.com.cn/tags/html_ref_httpmethods.asp

http://www.javanx.cn/20190227/get-post/

https://www.cnblogs.com/cexm/p/13435627.html

猜你喜欢

转载自blog.csdn.net/weixin_43901865/article/details/113134952