Skip to content

Latest commit

 

History

History
47 lines (34 loc) · 5.97 KB

GET和POST的区别.md

File metadata and controls

47 lines (34 loc) · 5.97 KB

GET和POST的区别

超文本传输协议HTTP的设计目的是保证客户端与服务端之间的通信,HTTP协议的工作方式是客户端与服务端之间的请求响应,在客户端与服务端进行请求响应时最常用的两种方法就是GETPOST

区别

  • GET是安全的、幂等的,而POST是 不安全的、不幂等的。
  • GET在浏览器回退或者刷新时是无害的,而POST会再次提交数据请求。
  • GET产生的URL地址可以作为书签保存,而POST不行。
  • GET请求会被浏览器主动cache,而POST不会主动缓存。
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  • GET请求在URL中传送的参数长度受URL长度限制,而POST的大小取决于后端配置。
  • GET参数只接受ASCII字符的数据类型,而POST没有限制,可以传输二进制数据。
  • GETPOST更不安全,因为参数直接暴露在URL上,所以不适合传递敏感信息。
  • GET参数通过URL传递,直接可见,POST的参数放在Request body中,不直接可见。

详解

上述的区别都是GETPOST在浏览器中的具体实现上的区别,例如现在广泛使用的Promise就是各种对于Promise/A+的规范promisesaplus.com的实现,在HTTP/1.1的规范的征求意见稿RFC中提到了语义这个词语,语义定义了一个类型的请求应该具有什么样的,例如GET的语义就应该是获取资源,POST的语义就是修改资源,如果在符合语法的前提下实现违背语义的行为也是可以做到的,例如使用GET修改资源或者使用POST获取资源,甚至使用GET发送body(这需要服务端能够配合解析),这是合法的请求但是这是不符合语义的请求,而且很有可能会带来一些副作用,所以在本质上GETPOST的区别是其语义的区别,甚至可以理解为GETPOST并没有什么区别,只要客户端与服务端能够配合发送与接收即可,一个敢发一个敢收就可以了,而上文所述的区别主要是在浏览器中具体实现上的区别。

关于安全性与幂等性,安全性是指访问接口时不会对服务端资源状态发生改变,幂等性是指对于同一接口的URI多次访问时,得到的资源状态是相同的。

  • GET: 安全的,幂等的,用于读取资源。
  • POST: 不安全的,不幂等的,用于服务端自动产生的实例号创建资源,更新部分资源。
  • PUT: 不安全的,幂等的,用于客户端的实例号创建资源,更新资源。
  • DELETE: 不安全的,幂等的,用于客户端实例号删除资源。

在浏览器点击后退操作时,如果将要返回的页面是GET请求的,那么将会安全的进行回退,如果将要返回的页面是POST请求的,例如使用<form>methodPOST去提交数据并跳转页面的话,浏览器会发出一个是否再次提交表单的确认提示。

关于GETPOST提交的参数长度的限制问题,GET是通过URL提交数据,因此GET可提交的数据量就跟URL所能达到的最大长度有直接关系,实际上HTTP协议对URL长度是没有限制的,但是在各种浏览器中对于URL长度是有限制的,而且限制的长度是不同的,一般使用不超过4K,此外服务端也会对于URL有各自的限制,当然服务端可以接收的URL长度大小是可以配置的,同样的,HTTP协议没有对POST进行任何限制,POST提交的数据大小一般是受服务器的主动配置来限定大小。

关于敏感信息不要使用GET进行传输主要有两个方面的考虑,首先使用GET传输敏感信息会直接暴露在URL上,会直接可见,此外使用GET传输的参数会被直接保存在浏览器的历史记录中以及服务器的日志中,当然HTTP协议本身就是一个明文传输的协议,无论是使用GET还是POST在中间人攻击等情况下都是能够拿到传输的数据的,如果需要避免中间人等攻击需要使用HTTPS进行数据的加密传输。

关于GET发送一个请求,POST发送两个请求的问题,同样这也是各种浏览器对于HTTP协议的具体实现的案例,而不涉及GETPOST的本质区别,关于这个具体的实现在各种浏览器上的表现并不相同,主要是浏览器的网络请求底层对于请求上优化的实现,例如需要使用POST传输一个大文件,那么浏览器就有可能首先发送一个数据包并携带少量数据去检测服务端是否能够接收这个文件,服务端在解析上传的文件时,总是会先完全解析全部的请求头部,服务器端总是希望能够了解请求的控制信息后,就能决定这个请求怎么进一步处理,是拒绝还是接收,如果服务端允许接收这个文件那么客户端会继续发送数据进行上传操作,如果服务端拒绝了就直接中断上传,这样用以节省提高数据吞吐和降低带宽的浪费。在本质上这和HTTP协议无关,这是浏览器在具体实现上做的一些优化,例如在内部设定一次POST的数据超过1KB就先只发请求头,否则就一次性全发,客户端甚至还可以做一些Adaptive的策略,统计发送成功率,如果成功率很高,就总是全部发等等。不同浏览器可以有各自的不同的方案,不管怎样做,优化目的总是在提高数据吞吐和降低带宽浪费。无论浏览器如何发送其总是符合HTTP协议的,是具体实现而不涉及GETPOST的本质区别。

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://zhuanlan.zhihu.com/p/25028045
https://www.zhihu.com/question/28586791
https://mp.weixin.qq.com/s?__biz=MzI3NzIzMzg3Mw==&mid=100000054&idx=1&sn=71f6c214f3833d9ca20b9f7dcd9d33e4