那些年被忽略的——HTTP的方法(Method)
安全方法和等幂方法
- 引入两个词语:
- 副作用,副作用指的是不会改变服务器的资源,搜索是无副作用的,注册是有副作用的。
- 等幂:值不变性,相同的请求得到相同的响应结果,不会出现相同的请求出现不同的响应结果。
安全方法
GET和HEAD方法只是执行没有影响的动作那就是获取资源,这些方法可以认为是安全的。
- 可以让用户代理调用的其他方法,比如
POST、PUT和DELETE,这些方法是特殊的,用户代理应该知道这些方法可能会执行不安全的操作。
- 在发起
GET请求资源的时候,完全不产生副作用是不可能的,但是用户不会请求产生的副作用,所以这些副作用不会影响用户。
等幂方法
- 方法可以有等幂的性质是因为除非出现出错或终止的问题,
N>0个相同请求的的副作用同单个请求的副作用是一样。方法GET、HEAD、PUT、DELETE都有这种性质。
- 方法
OPTION和TRACE不应该有副作用,因此具有内在的等幂性。
- 一个序列如果没有副作用,那么这个序列是等幂的。
OPTIONS
OPTION方法标明请求想得到请求/响应链上关于此请求里的URI(Request-URI)制定资源的通信选项信息。此方法允许客户端去判定请求资源的选项或服务器的能力。
- 此方法的响应是不能缓存的。
- 如果
OPTIONS请求消息里包括一个实体出题,那么媒体类型必须通过Content-type指明。虽然规范中没有定义如何使用这个实体主体,但是HTTP扩展可能会利用OPTIONS请求的消息主体去得到服务器更多的信息。一个服务器如果不支持OPTION请求的消息主体,会遗弃这个消息主体。
- 如果请求
URI是一个星号,OPTIONS请求将会应用于服务器的所有资源而不是特定资源。因为服务器的的通信选项通常依赖于资源,所以*请求只能在ping或者no-op方法才有用,除了允许客户端测试服务期的能力,做不了任何事情。
- 当
URI不是一个星号的时候,OPTIONS请求只能应用于请求URI指定资源的选项
200响应应该包含任何指明选项性质的头部,这些选项性质由服务器实现并且只适合那个请求的资源(比如Allow)。内容协商可能用于选择合适的响应格式。如果没有相应主题包含,响应应该包含一个值为0的Content-Length属性。
GET
GET方法可以获取请求URI的指定信息。如果请求URI涉及到一个数据生成过程,那么这个过程生成的数据应该被作为实体在响应中返回而不是源文本,除非源文本是这个过程的输出结果。
- 如果请求消息包含
If-Modified-Since,If-Unmodified-Since,If-Match,If-None-Match头部,GET的语义就会变成条件GET。一个条件GET方法会请求满足条件头部的实体。条件GET方法的目的是为了减少不必要的网络使用,通过允许利用缓存里的实体而不用频繁请求来实现。
- 如果请求方法包含一个
Range头部,那GET方法的语义就变成部分GET方法。一个部分GET会请求实体的一部分。部分GET方法的目的是为了减少不必要的网络使用,可允许客户端从服务器获取实体的部分数据,而不需要获取客户端本地已经拥有的部分实体数据。
- 如果这个响应满足
HTTP缓存的要求,GET请求的响应是可缓存的。
HEAD
HEAD和GET一样,除了服务器不能在相应里返回消息主体。HEAD请求响应里元信息应该和GET请求响应里的元信息一致。经常用HEAD方法来获取请求实体的元信息而不需要传输实体主体。可以测试超链接的有效性、可访问性和最近的改变。
HEAD请求的响应是可缓存的,因为响应里的信息可能被缓存用于更新以前那个资源对应缓存的实体。如果出现一个新的缓存实体和当前源服务器上的实体不同,可能是Conten-Length、Content-MD5、ETag或Last-Modified值的改变。那么缓存必须认为缓存项是过期的。
POST
POST方法是用于请求源服务器接受请求中的实体作为请求资源的方法。
POST被设计涵盖以下功能:
- 已存在的资源注释
- 发布消息
- 提供一个数据块
- 通过追加操作来扩展数据库
POST方法的实际功能由服务器决定,并且经常依赖于请求URI。POST提交的实体是请求URI的从属物,
POST方法执行的动作可能不会对请求URI所指的资源起作用,在这种情况下,200和204是合适的响应状态。这依赖于响应是否包含一个描述结果的实体。
- 如果资源被服务器创建,响应应该是
201并且包含一个实体,此实体描述了请求的状态。并且引用了这个资源和一个Location。
POST方法的响应是不可缓存的。除非响应里有合适的Cache-Control或者Expires头部。用户代理可以利用303响应去获得可缓存的响应。
PUT
PUT方法请求服务器去吧请求里的试题存储在请求URI下。如果请求URI指定的资源已经在源服务器上存在,那么此请求里的实体应该被当做是源服务器关于此URI所指定资源实体的最新修改版本。如果请求URI指定的资源不存在,并且此URI被用户代理定义为一个新资源,那么源服务就应该根据请求里的实体创建一个此URI所标识下的资源。如果一个新的资源被创建了,源服务器必须向用户代理发送201响应。如果已存在的资源被改变了,那么源服务器应该发送200或204响应。如果资源不能根据请求URI创建或改变,一个合适的错误响应应该给出反映问题的响应。实体的接收者不能忽略任何它不理解和不能不能实现的Content-*头部,并且必须返回501响应。
- 如果请求穿过一个缓存,并且此请求
URI指示了一个或多个当前缓存的试题,那么这些实体应该被看作是旧的。
PUT方法的响应是不可缓存的。
POST和PUT方法最根本的区别是请求URI的含义不同。POST请求里的URI指示一个能处理请求实体的资源,这个资源可能是一段程序,是一个数据接收过程,或者是一个网关,或者是一个单独接收注释的实体。而PUT方法请求的URI标识,用户代理知道这个URI的意图,并且服务器不能把这个请求应用于其他资源。如果服务器期望请求应用被用于一个不同的URI,必须发送301响应,用户代理可以自己决定是否重定向请求。
- 一个单独的资源可能会被许多不同的URI指定。但是,对于一个通用
URI的PUT请求,可以能会导致这个资源的其他URI请求被源服务器重定义。
HTTP/1.1没有定义PUT方法对源服务器的状态影响。
- 除非特别之处,
PUT方法请求里的实体头部应该被用于资源的创建或修改。
DELETE
DELETE方法请求源服务器删除请求URI指定的资源,这个方法可能会在源服务器上被人为的干涉。
- 客户端不能保证此操作能被执行,即使源服务器返回成功状态码。
- 服务器不应该指明成功,除非它打算删除资源或把资源移到一个不可访问的位置。
- 如果响应里包含描述成功的实体,响应应该是
200。如果DELETE动作还没有执行,应该以202(已接收)响应。如果DELETE请求方法已经执行但响应不包含实体,那么应该以204(无内容)响应。
- 如果请求穿过缓存,并且请求
URI指定了一个或多个缓存当前实体,那么这些缓存项应该被认为是过期的。
DELETE方法的响应不能被缓存。
TRACE
TRACE方法被用于激发一个远程的,应用层的请求消息回路。
TRACE方法让客户端测试到服务器的网路通路。发送一个请求返回一个响应,这就是一个请求响应回路。
- 最后的接收者也许是源服务器,也许是
Max-forwards为0的代理或网关。
TRACE请求不能包含一个实体。
TRACE允许客户端去了解数据被请求链的另一端接收的情况,并且利用那些数据信息去测试或诊断。
- 如果请求是有效的,响应应该在实体主体里包含整个请求信息,并且
Content-type的值为message/http。
TRACE方法的响应不能被缓存。
CONNECT
- 保留了
CONNECT方法,为了能动态切换到隧道代理。
总结
- 虽然现在的接口遍地是
GET和POST,我还是希望以后的接口可以语义化。充分使用HTTP协议里已经定义好的方法。
- 欢迎点赞、评论