HTTP协议中的GET和POST方法


两种最常用的 HTTP 方法是:GET 和 POST。


什么是HTTP

  • 超文本传输协议(HTTP)的设计目的是保证客户机和服务器之间的通信。
  • HTTP的工作方式是客户机与服务器之间的请求-应答协议
  • web 浏览器可能是客户端,而计算机上的网络应用程序也可能作为服务器端。

GET方法

在get方法中,查询字符串(名称/值对)是在GET请求的URL中发送的,例如:

1
https://www.baidu.com/baidu?isource=infinity&iname=baidu&itype=web&tn=98012088_9_dg&ch=7&ie=utf-8&wd=xxxxx

有关 GET 请求的其他一些注释:

  • GET 请求可被缓存

  • GET 请求保留在浏览器历史记录中

  • GET 请求可被收藏为书签

  • GET 请求不应在处理敏感数据时使用

  • GET 请求只应当用于取回数据


POST方法

在post方法中,查询字符串(名称/值对)是在POST请求的HTTP消息主体中发送的

有关 POST 请求的其他一些注释:

  • POST 请求不会被缓存

  • POST 请求不会保留在浏览器历史记录中

  • POST 不能被收藏为书签


比较 GET 与 POST

下面的表格列出了比较了两种 HTTP 方法的一般理解:GET 和 POST。

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

上图中,http协议对于URL长度其实是没有限制的,只是Web服务器浏览器对URI都有自己的长度限制

服务器的限制:接触的最多的服务器类型就是Nginx和Tomcat,对于url的长度限制是通过控制http请求头的长度来进行限制的,nginx的配置参数为large_client_header_buffers,tomcat的请求配置参数为 maxHttpHeaderSize。

浏览器的限制:每种浏览器也会对url的长度有所限制。


其他 HTTP 请求方法

下面的表格列出了其他一些 HTTP 请求方法:

方法 描述
HEAD 与 GET 相同,但只返回 HTTP 报头,不返回文档主体。
PUT 上传指定的 URI 表示。
DELETE 删除指定资源。
OPTIONS 返回服务器支持的 HTTP 方法。
CONNECT 把请求连接转换到透明的 TCP/IP 通道。

深入了解GET和POST方法

首先先来了解RFC:

征求意见稿(英语:Request For Comments,缩写为RFC),是由互联网工程任务组(IETF)发布的一系列备忘录。文件收集了有关互联网相关信息,以及UNIX和互联网社区的软件文件,以编号排定。目前RFC文件是由互联网协会(ISOC)赞助发行。

然后在来了解一下「语法」和「语义」semantic 的关系

一种语言是合法句子的集合。什么样的句子是合法的呢?可以从两方面来判断:语法和语义。语法是和文法结构有关,然而语义是和按照这个结构所组合的单词符号的意义有关。合理的语法结构并不表明语义是合法的。例如我们常说:我上大学,这个句子是符合语法规则的,也符合语义规则。但是大学上我,虽然符合语法规则,但没有什么意义,所以说是不符合语义的。

语义则定义了这一类型的请求具有什么样的性质。比如GET的语义就是「获取资源」,POST的语义是「处理资源」,那么在具体实现这两个方法时,就必须考虑其语义,做出符合其语义的行为。

当然在符合语法的前提下实现违背语义的行为也是可以做到的,比如使用GET方法修改用户信息,POST获取资源列表,这样就只能说这个请求是「合法」的,但不是「符合语义」的。 写到这里突然联想到XML里面的两个概念:Well Formed和Valid,似乎也正是语法和语义的理念呢。

上文说到方法是请求语义的主要来源,也即是还有次要来源,一些请求Header可以进一步修饰请求的语义,比如一个带上了 Range Header的GET请求就变成了部分请求。

RFC7231里紧接着定义了HTTP方法的几个特性:

  1. Safe - 安全
    这里的「安全」和通常理解的「安全」意义不同,如果一个方法的语义在本质上是「只读」的,那么这个方法就是安全的。客户端向服务端的资源发起的请求如果使用了是安全的方法,就不应该引起服务端任何的状态变化,因此也是无害的。 此RFC定义,GET, HEAD, OPTIONS 和 TRACE 这几个方法是安全的。
    但是这个定义只是规范,并不能保证方法的实现也是安全的,服务端的实现可能会不符合方法语义,正如上文说过的使用GET修改用户信息的情况。
    引入安全这个概念的目的是为了方便网络爬虫和缓存,以免调用或者缓存某些不安全方法时引起某些意外的后果。User Agent(浏览器)应该在执行安全和不安全方法时做出区分对待,并给用户以提示。
  2. Idempotent - 幂等
    幂等的概念是指同一个请求方法执行多次和仅执行一次的效果完全相同。按照RFC规范,PUT,DELETE和安全方法都是幂等的。同样,这也仅仅是规范,服务端实现是否幂等是无法确保的。
    引入幂等主要是为了处理同一个请求重复发送的情况,比如在请求响应前失去连接,如果方法是幂等的,就可以放心地重发一次请求。这也是浏览器在后退/刷新时遇到POST会给用户提示的原因:POST语义不是幂等的,重复请求可能会带来意想不到的后果。
  3. Cacheable - 可缓存性 顾名思义就是一个方法是否可以被缓存,此RFC里GET,HEAD和某些情况下的POST都是可缓存的,但是绝大多数的浏览器的实现里仅仅支持GET和HEAD。关于缓存的更多内容可以去看RFC7234。

在这三个特性里一直在强调同一个事情,那就是协议不等于实现:协议规定安全在实现里不一定安全,协议规定幂等在实现里不一定幂等,协议规定可缓存在实现里不一定可缓存。

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

POST的语义是根据请求负荷(报文主体)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST不安全,不幂等,(大部分实现)不可缓存。

参考文章:

HTTP协议中GET和POST方法的区别

HTTP 方法:GET 对比 POST

-------------本文结束 感谢您的阅读-------------
0%