part of RFC 2616 Fielding, et al.
9 方法定义
下面列出了有关HTTP/1.1协议的一些常见方法。尽管这些方法可以被扩展,但是不能假设这些额外的方法可以为单独扩展的客户端或服务器共享该方法的语义。
Host请求头字段()必须伴随所有HTTP/1.1请求。
9.1 Safe和Idempotent方法
9.1.1 Safe方法
开发者应该知道,用户通过软件在互联网上进行交互,我们应该小心的允许用户了解他们可能采取的任何行动,因为这些行为可能会对他们自己或其它人有意想不到的意义。
相关标准已经详细说明,GET和HEAD方法不能用于除了检索以外的其他目的。那么这些方法应该被认为是“安全的”。这允许用户代理以特殊的方式来表示其他方法,例如POST、PUT和DELATE,从而使用户意识到该请求可能存在不安全的动作的事实。
当然,服务器执行GET请求,不可能确保这不会产生副作用;实际上,一些动态资源把这种副作用当作是一个功能。这里有个重要的事情需要分清,就是用户没有请求副作用,所以不应对副作用负责。
9.1.2 Idempotent方法
"方法"同样拥有“幂等性”(除了错误或过期的情况),大于一次的相同请求与单独一次请求所产生的副作用是一样的。GET,HEAD,PUT,DELETE等方法共享该属性。另外,OPTIONS和TRACE方法不应该有副作用,所以本质上就是幂等的。
然而,多个请求的队列可能是非幂等的,尽管执行请求中的所有方法本身都是幂等的(如果一个序列的单次执行总是会产生一个结果,并且该结果并不会因该序列的部分或全部重新执行而改变,那么该序列就是幂等的)。比如,一个序列中的值会在稍后被修改,并且该序列的结果会依赖于此,那么该序列就是非幂等的。
根据定义,一个不产生副作用的序列是幂等的(假如没有在同一资源上执行并发操作)。
9.2 选项(OPTIONS)
OPTIONS方法表示对由“请求URI标识的请求/响应链”上可用的通信选项的信息的请求。此方法允许客户端确定与资源或服务器功能相关的选项和(或)需求,而不涉及资源操作或启动资源检索。对该方法的响应是不能缓存的。
如果一个OPTIONS请求包含了一个实体(entity-body),比如存在Content-Length或Transfer-Encoding,那么媒体类型就必须使用Content-Type字段所表示。尽管该规范没有定义这种主体的任何用处,未来的HTTP扩展可能会使用OPTIONS的实体在服务器上做更为详细的查询。如果服务器不支持该类型的扩展,则可以丢弃请求体。
如果请求的URI是一个“*”号,那么OPTIONS请求往往用于服务器而不是一个指定的资源。由于服务器的通信选项通常依赖于资源,所以“*”请求只能用于“ping”或“no-op”类型的方法;它除了允许客户端测试服务器的能力外什么也做不了。例如,它可以用来测试HTTP/1.1遵从(或缺少)的代理。
如果请求URI不是星号,则OPTIONS请求仅适用于与该资源通信时可用的选项。
一个200响应应包括指示服务器实现的可选特征的任何头字段,并适用于该资源(例如,ALLOW),也可能包括未由本规范定义的扩展。响应体(如果有的话)也应该包含关于通信选项的信息。这种实体的格式并不是由本规范定义的,但是可能会由未来有关于HTTP的扩展内容来定义。内容协商(Content negotiation)可以用来选择适当的相应格式。如果未包含响应体,则响应必须包含字段值为“0”的Content-Length字段。
Max-Forwards请求头字段可以用来在一个请求链中请求一个指定的代理。当一个代理在一个允许请求转发的绝对URI地址上接收到了一个OPTIONS请求时,代理必须检查Max-Forwards字段。如果Max-Forwards的字段值是“0”,代理则不能转发信息;相反的,代理应该用自己的通信选项进行响应。如果Max-Forwards的字段值是大于0的整数,那么代理的每一次转发必须消减该字段值。如果在请求中没有Max-Forwards字段,那么转发的请求中也不能存在Max-Forwards字段。
9.3 GET*
GET方法意味着检索请求URI标识的任何信息(以实体的形式)。如果请求URI指定的是一个数据产生的过程,那么应该将生成的数据作为实体返回,而不是返回该流程的原文本,除非该文本恰好是该过程的输出。
如果请求信息中包括了If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match,或者If-Range等字段,那么GET方法的语义就变成了“有条件的GET方法(conditional GET)”。条件GET(conditional GET)方法请求仅在符合条件头字段所描述的情况下才会传输实体内容。条件GET方法旨在减少不必要的网络请求,它允许刷新缓存的实体,而不需要多个请求或传输客户端里已经存在的数据。
如果请求信息中包含了一个Range头字段,那么GET方法就会变为“局部GET(partial GET)”。一个局部GET请求只获取实体的一部分内容(就像章节中描述的那样)。部分GET方法旨在完成对实体的部分检索而不传输客户端已经存在的数据来减少不必要的网络请求。
当且仅当它满足第13节中所描述的有关HTTP缓存的要求时,对GET请求的响应是可以被缓存的。
在应用表单时的相关安全策略请参阅小节。
9.4 HEAD
除了在响应中的不会返回消息体外,HEAD方法与GET方法并没有什么区别。在HEAD请求所返回的响应中所包含的头部源信息应该跟GET请求所返回的响应中的信息相同。该方法可用于在不转移实体本身的情况下获得请求所隐含的有关于实体的源信息。该方法通常用于测试超文本链接的有效性、可访问性以及最近的修改。
一个HEAD请求所返回的响应应该是可以缓存的,在该意义上来说,响应中所包含的信息应该可以用来更新之前资源中缓存的实体信息。如果新的字段值标示之前缓存的实体和现在的实体是不一样的(就像Content-Length,Content-MD5,ETAG或Last-Modified等字段表示的那样),那么缓存机制必须将该缓存条目视为过期的。
9.5 POST
POST方法用于请求源服务器接受请求中包含的实体作为请求队列中的请求URI所标识的资源的新下属。POST方法被设计为可以用一个统一的方式来覆盖以下的功能:
- 对现有资源的注释; - 向公告牌,新闻类,邮件列表或者类似的文章类发送信息; - 向数据处理过程提供数据块,例如提交表单的结果; - 通过附加操作扩展数据库。
POST方法执行的实际函数由服务器决定,并且通常依赖于请求URI。POST所发布的实体内容从属于该URI,就像一个文件从属于包含它的目录,新闻文章从属于发布它的新闻组,或者记录从属于数据库一样。
POST方法执行的操作可能不会产生可以由URI标识的资源。在这种情况下,200 (OK)或204 (No Content)都是适当的响应状态,这取决于响应是否包含描述结果的实体。
如果在源服务器上创建了一个资源,那么响应应该是201(Created),并包含一个描述请求状态并引用新资源的实体和一个Location头字段。(详情见14.30章节)
对该方法的响应是不可缓存的,除非响应包含适当的Cache-Control或Expires头字段。但是,可以使用303(See Other)响应指示用户代理检索可缓存资源。
POST请求必须遵守第8.2节中规定的有关消息传输要求。
有关安全性相关的问题请查阅节
9.6 PUT
PUT方法请求一个被请求URI封闭的指定实体。如果请求URI指向了一个已经存在的资源,那么被封闭的实体被认为是存在于原服务器上的一个修改版。如果一个请求URI没有指向一个已经存在的资源,并且该URI能够被请求的客户端视为一个新的资源,那么服务器就可以用该URI创建一个新的资源。如果一个新的资源被创建了,那么源服务器必须使用201(Created)来通知客户端。如果一个已存在的资源被修改了,那么服务器需要返回一个200 (OK) 或204 (No Content)状态码来告知客户端用来表明修改的完成。如果在该请求URI下的资源无法被创建或者修改,应该返回一个用来反映该错误的适当的错误响应。实体的接收者不能忽略它不理解或实现的任何Content-*(例如Content-Range)头字段,并且必须在这种情况下返回501(Not Implemented)响应。
如果该请求通过了一个缓存,并且该请求URI标识了一个或多个当前缓存的实体。那么,那些缓存实体被视为是过期的。该方法的响应不能被缓存。
POST和PUT请求之间的根本区别在于请求URI所反映的不同含义。POST请求中的URI标识的资源将操作该封闭的实体。该资源可能是一个接受数据的进程、某个其他协议的网关或接受注释的单独实体。相比之下,在PUT请求中的URI在请求中标识了被附加的实体——用户代理知道URI的意图,服务器不应尝试将该请求应用到其他资源。如果服务器希望将请求应用到不同的URI,它必须发送301(Moved Permanently)响应;然后,用户代理可以自己决定是否重定向该请求。
一个资源可能会被很多不同的URI所标识。比如,文章可能有一个用于标识“当前版本”的URI,该URI与标识每个特定版本的URI分开。在这种情况下,常规URI上的PUT请求可能导致请求到由源服务器定义的多个其他URI。
HTTP/1.1没有定义PUT方法如何影响源服务器的状态。
PUT请求必须遵守第8.2节中规定的消息传输要求。
PUT方法除非被特定的实体头(entity-header)所指定,否则PUT请求中的实体头( entity-headers)应该应用于PUT方法创建或修改的资源。
9.7 DELETE
DELETE方法请求服务器删除被请求URI标识的资源。这种方法可能会被源服务器上的人工干预(或其他方法)覆盖。即使从源服务器返回的状态代码表明操作已经成功完成,也不能保证客户端已经执行了该操作。但是,服务器不应指示成功,除非在给定响应时它打算删除资源或将其移动到不可访问的位置。
如果响应包含描述状态的实体,那么成功的响应应该是200 (OK);如果操作尚未完成,响应应该是202(Accepted);如果操作已完成,但响应不包含实体,则响应应该是204(No Content)。
如果请求了一个缓存,并且请求URI标识一个或多个当前缓存的实体,那么这些条目应该被视为过期的。对该方法的响应不能缓存。
9.8 TRACE
跟踪方法用于调用请求消息的远程、应用层回环。请求的最终接收者应该把返回给客户端的消息作为200(OK)响应的实体。最终的接收者要么是源服务器,要么是接收请求中最大转发值为0的第一个代理或网关(参见14.31节)。TRACE 请求不能包含实体。
TRACE 方法允许客户端查看在请求链的另一端接收到什么,并将该数据用于测试或诊断信息。Via头字段(第节)的值特别值得关注,因为它充当请求链的跟踪。使用Max-Forwards头部字段允许客户端限制请求链的长度,这对于在无限循环中测试代理转发消息链非常有用。
如果请求是有效的,响应应该包含实体主体中的整个请求消息,其中包含了一个值为“message/http”的Content-Type。TRACE方法的响应是不能缓存的。
9.9 CONNECT
本规范保留了CONNECT方法名,以便与可以动态切换为隧道的代理(例如,SSL隧道)一起使用。