因为最近的项目需求,经常使用到http请求,但我在平时的开发中最常用的请求也就只有POST和GET,对于其他十多种请求基本上不了解,也没有使用过。
所以干脆学一学这十多种HTTP请求之间的区别,然后记录成文章。
在接口测试工具postman中,新建request后在选择请求方式的地方,我们可以看到数十种协议(当然,这些并不是完整的,仍有部分方法在其中没有列出),分别是GET/POST/PUT/PATCH/DELETE/COPY/HEAD/OPTIONS/LINK/UNLINK/PURGE/LOCK/UNLOCK等,其中最常用的就是POST和GET,后面的不仅没怎么使用过,有些甚至都没听说过,这篇文章就来整理一下这15种不同协议之间的区别,以及它们的用法。
前置知识
我们首先来了解一下HTTP请求和响应报文的结构。对于HTTP请求,服务器和客户端之间使用HTTP报文进行交互。一般来说,报文是有三部分组成,分别如下结构:
报文头部 |
空行(\r\n) |
报文主体 |
正如上表所述,报文头部和主体由一个空行分隔,其中空行是由一个回车符和一个换行符组成,在报文头部中,同样也使用到了许多回车+换行符来进行每一行的分割。在报文头部中又分为请求行或状态行(分别对应请求报文和响应报文),以及首部字段。其中首部字段就是我们常说的header。请求行中包含了请求方法、请求URI(统一资源标识符,和URL统一资源定位符有所区别)和HTTP版本。状态行中包含了响应结果码、原因短语和HTTP版本。
比如对此网站主页进行GET请求,使用的HTTP版本为1.1,则请求行内容如下:
1 GET http://kalinote.top/ HTTP/1.1
如果服务器正常响应,则返回报文状态行如下:
1 HTTP/1.1 200 OK
首部字段就不多说了,就是单纯的header的Key: Value;形式。我们今天所需要学习的,就是请求行的第一个关键字(词),也就是HTTP请求方法。也就是客户端在对服务器进行请求时,告诉服务段客户端的意图。
GET
对于最常用的两种方法之一,GET的作用是获取资源。
该方法用于请求已经被URI识别的资源。请求的资源会在返回前进行解析,然后返回响应内容。比如如果请求的资源是文本则直接返回文本,如果请求的内容是一段程序或其他可解析的内容,则返回执行结果或解析后的结果。
POST
第二种最常用的就是POST了,POST的主要作用是传送实体的主体。
POST和GET很像,区别是POST一般用于传输实体的主体,比如在data中传输一些数据。而POST一般不直接用于资源请求(区别于GET方法)使用POST方法进行请求时,可以在请求头中添加Content-Length: xxx来标明所传输数据的长度。
PUT
相对于GET和POST,PUT就不这么常用了,当然,后续要介绍的其他请求方法也是如此(指不那么常用)。
在标准定义中,PUT方法一般用于文件上传(类似于FTP),该请求方法要求在请求的报文主体中包含所需上传的文件内容,然后保存到URI指定的位置。不过因为PUT方法本身不带权限验证,所以实际上应该也没有多少人将该请求方法真正用于文件传输。
不过该请求方法在RESTful的设计中还是有作用的,这一点我们在下面单独介绍。
DELETE
DETELE单词的本意是删除,顾名思义,是用于删除的请求。
在标准定义中,DELETE请求是用来删除文件的,这个请求和PUT请求可以组合使用。不过问题和PUT一样,该请求本身不带权限认证,所以应该也没有人将其单独作为"删除文件"的请求来使用吧。
RESTful设计
在上面介绍到的四种请求方式中,有两种(PUT,DELETE)都不会被经常使用到,不过我说过其在RESTful设计中仍有作用,现在单独来简单介绍一下RESTful设计。
RESTful设计指的就是遵循REST的设计,REST的全称为Representational State Transfer,翻译成中文即表征状态转移。单从名字上来看,可能不太会知道这种设计是做什么的。简单来说,REST是一种不受强制性约束的风格,其中心思想为:在对资源进行访问时,使用行为动作来进行操作的区分。
比如,对于用户的操作,有接口 http://localhost:8080/users
对于该接口,我们如果要分别实现对用户的增删查改,可以设计以下请求方式:
请求接口地址 | 请求方法 | 作用 |
http://localhost:8080/users/1 | GET | 查询id为1的用户信息 |
http://localhost:8080/users | POST | 新增、保存用户 |
http://localhost:8080/users | PUT | 修改、更改用户信息 |
http://localhost:8080/users/1 | DELETE | 删除id为1的用户 |
根据上述例子可以看出,对于user的所有操作(增删查改)都是基于一个接口的不同请求方法来实现的,这种设计就是所谓的REST设计,而不是单独设计接口,并且全部使用POST方法。
对于REST设计就不进行过多介绍了,不过大家可以看到,在REST设计中,我们使用到了PUT和DELETE请求,分别用作删除和更新,这跟其标准定义中的使用方法不太一样,但是也被用到了实际接口当中。
下面继续介绍其他请求方式。
HEAD
该方法用于获取报头。该方法与GET很像,区别在于HEAD方法不返回报文主体,一般来说,HEAD请求用于确认URI的有效性及资源更新时间。
OPTIONS
该方法用户询问服务器所支持的方法,比如在上面的RESTful介绍中使用到的例子,对http://localhost:8080/users使用OPTIONS请求,就能得知其接口支持GET/POST/PUT/DELETE四种方法。
结果会在响应体中表明。
TRACE
根据协议,服务器在收到trace请求后,应回显所收到的数据,即服务器返回自己所收到的数据。
发送请求时,在头的Max-Forwards字段中填入数值,每经过一个服务器端该值减1。数值为0时停止传输。最后接收到请求的服务器端则返回200的响应码。
客户端通过TRACE请求可以知道发出去的数据是如何被传输加工和篡改的,不过该方法实际不太会被使用到。
CONNECT
要求使用隧道协议进行TCP通信。主要使用SSL和TLS协议把通信内容加密后经过网络隧道传输。在使用该请求方法时,请求头格式为 CONNECT 代理服务器名:端口号 HTTP版本
比如:
CONNETCT proxy.kalinote.top:8080 HTTP/1.1
以上8种请求为HTTP/1.1中所定义的8中请求。下面介绍的请求本身使用不多,所以相关资料也很少,只做了解即可。
LINK和UNLINK
对于这两个请求,在网上能找到的相关信息很少,在各种官方文档中也没有发现相关信息,通常对于这两种请求的解释是对服务器资源进行链接及移除链接,不过可以得知的是,这两种方法已经没有人再使用了。
MOVE/COPY/LOCK/UNLOCK
这两种请求方法比较类似,所以放到一起说明。
MOVE是请求服务器将指定的页面移至另一个网络地址,而COPY是请求服务器将指定的页面拷贝至另一个网络地址。LOCK方法用于取出任何访问类型的锁并刷新现有锁,UNLOCK则是解锁。
这几种请求方法在RFC 4918中被定义(9.8-9.11节)。我把文档链接放在这里,如果真的有需要用到可以进文档详细了解。
PATCH
实体中包含一个表,表中说明与该 URI 所表示的原内容的区别。
WRAPPED
允许客户端发送经过封装的请求。
MKCOL
允许用户创建资源。
这些请求方式在网上能找到的资料实在是太少,如果有需要详细了解的,可以去RFC文档看其详细定义,这里能找到对应方法的RFC文档。