TOC

HTTP 方法

https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods

方法清单

  • GET R 查
  • POST C 增
  • PUT U 改
  • DELETE D 删
  • PATCH U 改
  • HEAD 和 GET 相同,不过只返回请求头,不返回请求体
  • OPTIONS 返回这个请求支持的 HTTP 方法
  • TRACE 返回服务器收到的请求,调试用
  • CONNECT 为代理服务器准备的 HTTP 隧道方法

PATCH 和 PUT 的区别:PUT 是使用新版本来替换旧版本,PATCH 则是在旧版本的基础上修改。

  1. HTTP/1.0 只定义了 HEAD, GET, POST 三个方法,HTTP/1.1 增加了 PUT, DELETE, OPTIONS, TRACE, CONNECT 五个方法。
  2. PATCH 方法定义在 RFC 5789: PATCH Method for HTTP 中,目前还是一个草案,不在 HTTP/1.1 中。
  3. 除了 PATCH 方法之外,其实还出现过 LINK, UNLINK 两个方法,不过后来直接被无视了。
    甚至和 PUT, DELETE 一同列在 HTTP/1.0 标准的 Additional Request Methods 中
    而且还出现在了 HTTP/1.1 草案(RFC 2616)中
  4. TRACE, CONNECT 这两个方法很多 HTTP 服务都不支持,甚至有些服务都不支持 OPTIONS。
  5. Django 不支持 PUT, PATCH 方法(拿不到 body)。

示例

> OPTIONS / HTTP/1.1
> Host: www.markjour.com
> User-Agent: curl/7.74.0
> Accept: */*

< HTTP/1.1 200 OK
< Date: Sat, 11 Jan 2014 06:59:50 GMT
< Server: Apache
< Allow: OPTIONS,GET,HEAD,POST
< Vary: Accept-Encoding,User-Agent
< Content-Length: 0
< Content-Type: text/html
> GET / HTTP/1.1
> Host: www.baidu.com
> User-Agent: curl/7.74.0
> Accept: */*

< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
< Connection: keep-alive
< Content-Length: 2443
< Content-Type: text/html
< Date: Sat, 11 Jan 2014 06:52:33 GMT
< Etag: "588603fd-98b"
< Last-Modified: Mon, 23 Jan 2017 13:24:13 GMT
< Pragma: no-cache
< Server: bfe/1.0.8.18
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/

分类

RFC 7231 中的 Safe Methods,Idempotent Methods,Cacheable Methods。

  1. 安全:不会对资源产生影响(副作用除外,比如:请求计数,计费,日志等):
    • GET
    • HEAD
    • OPTIONS
    • TRACE
  2. 幂等:重复请求也不会对资源产生影响:

    • 上面四个安全方法自不用说
    • PUT
    • DELETE

    为什么 XXX 不幂等

    • POST 可能多次创建资源
    • PATCH 根据语义,对计数 +1 这种场景使用 PATCH 方法,这样的话,自然不是幂等
      如果直接赋值修改原数据的部分属性,则是幂等的(可以看作是对属性的批量 PUT 替换)
    • CONNECT 隧道而已,里面的请求具体是什么都不知道
  3. 可缓存(该小节在 RFC 2616 没有):

    • GET
    • HEAD
    • POST
    • PATCH

    PUT,DELETE 可以导致之前的相关缓存失效。

    为什么 POST/PATCH 方法 cacheable

    RFC 2616:

    Some HTTP methods MUST cause a cache to invalidate an entity. This is either the entity referred to by the Request-URI, or by the Location
    or Content-Location headers (if present). These methods are:
    - PUT
    - DELETE
    - POST

    RFC 7231:

    this specification defines GET, HEAD, and POST as cacheable, although the overwhelming majority of cache implementations only support GET and HEAD.

    Mozilla Developer Network:

    Only if freshness information is included

    根据相关 RFC,如果响应头中有 Expires, Cache-Control 头,可以缓存 POST/PATCH。
    我想,这个可能是为了避免资源重复创建而设计?
    不过现实是,没有浏览器或服务器支持缓存 POST/PATCH 请求。

备注:最终可缓存状态还取决于 HTTP 状态码, 必须是 200、203、204、206、300、301 才可以缓存。

拓展

当然,只需要客户端和服务器端都能支持,请求方法可以自定义,如:

  • LIST 列出资源,和 GET 方法对应
  • UPLOAD 上传
  • DOWNLOAD 下载
  • EXIST 是否存在
  • COLLECT 收藏
  • STAR 星标
  • VOTEUP 赞
  • VOTEDOWN 踩
  • 等等

Update @ 2020-04-01:

WebDAV 协议就可以看作是一个 HTTP 拓展, 增加了以下方法的支持:

  • COPY 复制
  • LOCK 锁定
  • MKCOL 创建集合(目录)
  • MOVE 移动
  • PROPFIND 查询属性
  • PROPPATCH 修改属性
  • UNLOCK 解锁

附:相关 RFC

参考资料与拓展阅读