youyichannel

志于道,据于德,依于仁,游于艺!

0%

GET VS POST

GET 和 POST 的区别

RFC文档:

  • GET:https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.1
  • POST:https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.3

根据 RFC 文档规范,GET 的语义是从服务器获取指定的资源,资源形式没有限定,可以是静态文本、页面、图片、视频等等。

GET 请求参数一般是写在 URL 中的,URL 只支持 ASCLL 编码,所以 GET 请求的参数只允许是 ASCLL,像一些中文就会被转义,而且浏览器会对 URL 的长度有限制,但是 HTTP 协议本身对 URL 长度并没有做出任何规定。

根据 RFC 文档规范,POST 的语义是根据请求负荷(报文 Body)对指定资源做出操作,不同的资源类型所属的操作方式也不同。

POST 请求携带的数据一般是写在报文 Body 中,Body 中的数据可以是以任意格式存在的,只要 Client 和 Server 协商一致即可,而且浏览器也不会对 Body 的大小做出限制。

GET 和 POST 方法都是「安全和幂等」的吗?

什么是安全和幂等:

  • 在 HTTP 协议中,「安全」是指请求方法不会「破坏」服务器上的资源。
  • 「幂等」是指多次执行同样的操作,结果都是相同的。

从 RFC 文档规范的语义来看:

  • GET 方法是安全且幂等的。因为 GET 请求是「只读」操作,无论操作多少次,服务器上的资源都是安全的,且每次的结果都是相同的。因此,可以对 GET 请求的数据做缓存,缓存位置可以在浏览器本身(避免浏览器发送请求),也可以在代理服务器上(比如 Nginx),而且在浏览器中 GET 请求可以保存为书签
  • POST 方法 因为是「新增或者修改资源」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以是不幂等的。因此,浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签。

小结

  • GET 的语义是获取指定的资源。 GET 方法是安全、幂等、可被缓存的。
  • POST 的语义是根据请求负荷(报文 Body)对指定资源做出操作,不同的资源类型所属的操作方式也不同。POST 方法是不安全、不幂等、(大部分实现)不可缓存。

⚠️注意:上述是从 RFC 规范定义的语义来分析的。但是实际过程中,开发者不一定会按照 RFC 规范定义的语义来实现 GET 和 POST 方法。比如:

  • 使用 GET 方法实现新增或删除数据的请求,这样实现的 GET 方法就不是安全和幂等的。
  • 使用 POST 方法实现查询数据的请求,这样实现的 POST 方法就是安全和幂等的。

如果「安全」指的是信息是否会被泄漏的话,虽然 POST 用 Body 传输数据,而 GET 用 URL 传输,这样数据会在浏览器地址栏看到,但是并不能说 GET 不如 POST 安全。因为 HTTP 传输的内容都是明文的,虽然在浏览器地址栏看不到 POST 提交的 Body 数据,但是只要抓个包就可以看到了。因此,要避免传输过程中数据被窃取,就要使用 HTTPS 协议,这样所有的 HTTP 的数据都会被加密传输。

一些问题

GET 请求可以携带 Body 吗?

RFC 规范并没有规定 GET 请求不能带 Body。理论上,任何请求都可以带 Body 的,只是因为 RFC 规范定义的 GET 请求是获取资源,所以根据这个语义不需要用到 Body。

另外,URL 中的查询参数也不是 GET 所独有的,POST 请求的 URL 中也可以有参数的。

POST 请求可以被缓存吗?

POST请求通常不应该被缓存。按照HTTP协议的规定,POST请求是用于向服务器提交数据,可能会对服务器状态产生影响,因此不应该被缓存。POST请求通常用于提交表单数据、上传文件等,这些操作对服务器状态有意义,因此缓存这些请求可能导致不可预测的结果。

然而,有些情况下,如果POST请求的响应具有可缓存性,例如响应包含了合适的Cache-Control头或Expires头,那么客户端或代理服务器可能会缓存这些响应。但这种情况相对少见,并且需要在特定的环境下谨慎使用,以确保缓存的正确性和一致性。