zoukankan      html  css  js  c++  java
  • 计算机网络——谈谈HTTP中GET与POST的区别

    一、前言

      今天研究了一下HTTP协议中,GET方法与POST方法的区别。一研究发现,GETPOST完全不似我学习Web开发时了解的那般,它们之间的关系完全颠覆了我之前的理解。这篇博客我就来从两个层面谈一谈GETPOST的区别——浏览器层面以及报文层面。


    二、正文

      2.1 浏览器层面的区别

      GETPOST方法在浏览器层面的区别大部分人或多或少都知道一些,它主要包含以下几个方面:

      通过以上区别,我们归纳为以下两点:

    • GET:它用来向服务器请求资源,所以没有副作用,而且它是幂等的,可以被缓存;
    • POST:用来请求服务器修改数据,所以有副作用,它是非幂等的,不能被缓存;

    HTTP中的幂等:每次请求会产生同样的副作用。

    GET是幂等的,因为它只是请求资源,不会对服务器产生影响,也就是没有副作用,所以是幂等的;而POST请求不是幂等,因为它修改了数据,每一次请求都会再次造成副作用。

      上面列举的这些区别,实际上有一些是存在因果关系的,比如POST用来请求服务器修改数据,所以每一次POST请求在理论上都会对服务器的数据进行修改,正因为如此,才有了这几条:

    1. 刷新时需要重新提交数据,以获取最新的资源;
    2. 不可缓存,因为POST请求会修改资源,所以缓存旧资源没有意义;

      浏览器将GET请求的数据放入URL中,而POST请求的数据放入body中,所以才有了下面几条:

    1. POST请求更加安全,因为GET请求直接将数据放入URL中,用户直接可以看到,但是POST的数据放入body中,用户无法直接看见;
    2. GET请求的数据只允许ASCII字符,因为数据在URL中,URL中只允许ASCII字符,而POST数据放入body中,body中允许二进制数据;

      但是,以上这些区别都是浏览器以及Web服务器遵循HTTP的约定实现的,并不是GETPOST的本质区别,下面我们从报文层面分析GETPOST的区别。


      2.2 报文层面的区别

      这里我直接给出结论:GET方法和POST方法本质没有太大区别,仅仅报文格式以及方法名称不同。不论是GET方法还是POST方法的报文,都是HTTP报文,而HTTP是基于TCP/IP做数据传输的,也就是说,在传输层,这两种方法的报文传输方式没有任何的区别。在约定中,GET方法的数据被放入URL,而POST报文的数据被放入body就是格式上的区别,但是这也不是绝对的。


      2.3 深入理解它们的区别

      下面我就从本质层面来说明对以上所说的区别做一个解读:

    (1)GET方法用来向服务器请求资源,而POST方法请求服务器修改数据

      这一点正是HTTP规范中对这两个方法的约定,但是,仅仅只是约定,并不是强制。也就是说,我们完全可以通过GET方法请求服务器修改数据,而通过POST方法向服务器请求资源。对于很多Web开发的初学者,应该都干过类似的事情,比如做使用Servlet或者SpringMVCWeb开发,混用GETPOST。所以说,对于这一条区别,并不是一定的。

    (2)GET方法数据被放入URL,而POST放入body

      这是也是HTTP规范对这两种方法报文的约定,而浏览器在创建请求报文时是遵照这个约定实现的,仅此而已。这也就是说,对于GET请求,我们也可以将数据放入body中,而对于POST的数据,我们也能够放入URL中。我们违反这个约定,报文依旧可以正常传输,只要服务器的实现支持,就能够正常的获取数据。

    (3)GET方法发送的数据有限制(长度和类型),而POST没有

      我们前面说过,GET方法只能发送ASCII字符数据,且数据的长度是有限制的,而POST可以发送二进制的数据,且长度没有限制。首先从数据类型来说,不是GET方法只能发送ASCII字符数据,而是URL中只能放入字符数据,而GET方法的数据被放入URL,自然只能被URL所限制。如果我们在GET报文的body中放入数据,照样能够放入二进制数据。再来说说数据长度,HTTP规范中并没有限制URL的长度,真正限制URL长度的是浏览器,浏览器为了方便处理数据,以及安全性考虑,对URL的长度做了限制。但是,HTTP规范并没有限制URL长度,我们完全可以通过编写代码的方式,创建一个包含很长很长的URLHTTP报文,是可以正常传输的。

    (4)POST方法比GET方法更加安全

      这种说法的依据就是浏览器不会把POST的数据放入URL,用户不能直接看见,所以认为POST更加安全。但是在数据传输的过程中,GETPOST的报文传输是没有区别的,都是通过TCP连接进行传输。只要我们通过抓包软件,抓取到了HTTP报文,其实它们携带的数据都是直接可见,没有任何安全性可言。所以,从严格意义上来讲,GETPOST的安全性没有太大区别。若想要安全,应该使用HTTPS

    (5)POST请求会发送两个TCP报文

      网上还流传着它们之间的另一个区别,就是说浏览器会将POST请求的headerbody分开来发送,产生两个TCP报文段,先发送header,接收到服务器响应的状态码100之后,再发送body部分。但是,HTTP规范中并没有明确说明这一点,而且在实际的测试中,也没有发生这种情况。所以可以认为,这只是某些浏览器的自主实现,并不是POST的必然行为。


    三、总结

      我们谈论GETPOST的区别时,应该像上面一样,分情况进行讨论。在浏览器层面,它们之间有许许多多的区别,有些是HTTP规范的约定,而大部分其实还是浏览器的自主实现;而从本质上来看,两种其实没有太大区别。


    四、参考

  • 相关阅读:
    css 定位
    css inline忽略宽和高
    css clear属性
    关系型数据库与nosql
    链接标签<a>的css定义规则
    1em=16px
    text-align的justify属性
    2393Cirno的完美算数教室 容斥
    bzoj4665小w的喜糖 dp+容斥
    bzoj4558[JLoi2016]方 容斥+count
  • 原文地址:https://www.cnblogs.com/tuyang1129/p/12570894.html
Copyright © 2011-2022 走看看