HTTP请求方法GET和POST

HTTP请求方法GET和POST的区别,出现在面试题目中,网上也有很多总结。但是多看看RFC2616和RFC7321就发现那些总结有些问题。

一般理解

下面是普遍的理解,来自w3school的整理

GET后退按钮/刷新无害,POST数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
GET书签可收藏,POST为书签不可收藏。
GET能被缓存,POST不能缓存 。
GET编码类型application/x-www-form-url,POST编码类型encodedapplication/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。
GET历史参数保留在浏览器历史中。POST参数不会保存在浏览器历史中。
GET对数据长度有限制,当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。POST无限制。
GET只允许 ASCII 字符。POST没有限制。也允许二进制数据。
与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET !POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。
GET的数据在 URL 中对所有人都是可见的。POST的数据不会显示在 URL 中

误解分析

  • 响应是否能够缓存,是由响应中的缓存相关首部决定的,比如Cache-Control和Expire。并不是由方法get或者post决定是否可以缓存,虽然基本上都是缓存get请求的响应,设计get方法概念上就是用来获取信息的
  • 长度限制,本质上是因为GET方法请求参数附着于URL上,POST提交的数据在HTTP请求体中。虽然可以说是不同点,但是更多的是关于URL和HTTP的不同,两个有关系但是没有对比性
  • 编码也是,是URL采用的ASCII编码,而HTTP请求体编码有多种选择
  • 安全性问题的第一个解释是,get请求和post请求,一个主要用来获取信息,一个主要用来提交信息。RFC7321中的请求方法规范的安全性,只获取信息的get方法更具有安全性。
  • 安全性的第二个问题是,HTTP请求本身是明文传递的,所以无论是URL带请求参数或者HTTP请求体,都不安全。如果解决安全性,要使用SSL/TSL进行加密才可以解决

正确认识

HTTP方法的特征

 安全性

如果方式是只读的,则被认为是“安全的”方法。客户端向服务端的资源发起的请求如果使用了是安全的方法,就不应该引起服务端任何的状态变化,因此也是无害的。 此RFC定义,GET, HEAD, OPTIONS 和 TRACE 这几个方法是安全的

但是这个定义只是规范,并不能保证方法的实现也是安全的,服务端的实现可能会不符合方法语义,正如上文说过的使用GET修改用户信息的情况。
引入安全这个概念的目的是为了方便网络爬虫和缓存,以免调用或者缓存某些不安全方法时引起某些意外的后果。User Agent(浏览器)应该在执行安全和不安全方法时做出区分对待,并给用户以提示。

幂等性

幂等的概念是指同一个请求方法执行多次和仅执行一次的效果完全相同。按照RFC规范,PUT,DELETE和安全方法都是幂等的。同样,这也仅仅是规范,服务端实现是否幂等是无法确保的。
引入幂等主要是为了处理同一个请求重复发送的情况,比如在请求响应前失去连接,如果方法是幂等的,就可以放心地重发一次请求。这也是浏览器在后退/刷新时遇到POST会给用户提示的原因:POST语义不是幂等的,重复请求可能会带来意想不到的后果。

可缓存性

 可缓存性 顾名思义就是一个方法是否可以被缓存,此RFC里GET,HEAD和某些情况下的POST都是可缓存的,但是绝大多数的浏览器的实现里仅仅支持GET和HEAD。关于缓存的更多内容可以去看RFC7234。

总结

GET的语义是请求获取指定的资源。GET方法是安全、幂等、可缓存的(除非有 Cache-ControlHeader的约束),GET方法的报文主体没有任何语义。

POST主要用来提交信息,包含请求主体。POST方法不安全,不幂等,(大部分实现)不可缓存(不实现)。

100(Continue)状态码

参考

  1. RFC7231
  2. get和post?--知乎的优秀回答

猜你喜欢

转载自www.cnblogs.com/Jamie1032797633/p/10897633.html