Open Qingquan-Li opened 6 years ago
本文整理来源以下资料: HTTP 接口设计指北 浏览器缓存机制
关于 HTTP Methods 语义的说明(http1.1):
OPTIONS
HEAD
GET
200 OK
POST
201 Created
PUT
PATCH
DELETE
204 No Content
Location
重定向的新地址都需要在响应头 Location 中返回
303
403 Forbidden
Authorization
WWW-Authenticate
Allow
Content-Type
404 Not Found
Retry-After
501 与 405 的区别是:405 是表示服务端不允许客户端这么做,501 是表示客户端或许可以这么做,但服务端还没有实现这个功能
501
405
在调用接口的过程中,可能出现下列几种错误情况:
服务器维护中,503 状态码
503
HTTP/1.1 503 Service Unavailable Retry-After: 3600 Content-Length: 41 {"message": "Service In the maintenance"}
发送了无法转化的请求体,400 状态码
400
HTTP/1.1 400 Bad Request Content-Length: 35 {"message": "Problems parsing JSON"}
服务到期(比如付费的增值服务等), 403 状态码
403
HTTP/1.1 403 Forbidden Content-Length: 29 {"message": "Service expired"}
因为某些原因不允许访问(比如被 ban ),403 状态码
HTTP/1.1 403 Forbidden Content-Length: 29 {"message": "Account blocked"}
权限不够,403 状态码
HTTP/1.1 403 Forbidden Content-Length: 31 {"message": "Permission denied"}
需要修改的资源不存在, 404 状态码
404
HTTP/1.1 404 Not Found Content-Length: 32 {"message": "Resource not found"}
缺少了必要的头信息,428 状态码
428
HTTP/1.1 428 Precondition Required Content-Length: 35 {"message": "Header User-Agent is required"}
发送了非法的资源,422 状态码
422
HTTP/1.1 422 Unprocessable Entity Content-Length: 149 { "message": "Validation Failed", "errors": [ { "resource": "Issue", "field": "title", "code": "required" } ] }
所有的 error 哈希表都有 resource, field, code 字段,以便于定位错误,code 字段则用于表示错误类型:
error
resource
field
code
invalid
required
not_exist
already_exist
大部分接口应该在响应头中携带 Last-Modified, ETag, Vary, Date 信息,客户端可以在随后请求这些资源的时候,在请求头中使用 If-Modified-Since, If-None-Match 等请求头来确认资源是否经过修改。
Last-Modified
ETag
Vary
Date
If-Modified-Since
If-None-Match
如果资源没有进行过修改,那么就可以响应 304 Not Modified 并且不在响应实体中返回任何内容。
304 Not Modified
$ curl -i http://api.example.com/#{RESOURCE_URI} HTTP/1.1 200 OK Cache-Control: public, max-age=60 Date: Thu, 05 Jul 2012 15:31:30 GMT Vary: Accept, Authorization ETag: "644b5b0155e6404a9cc4bd9d8b1ae730" Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT Content
$ curl -i http://api.example.com/#{RESOURCE_URI} -H "If-Modified-Since: Thu, 05 Jul 2012 15:31:30 GMT" HTTP/1.1 304 Not Modified Cache-Control: public, max-age=60 Date: Thu, 05 Jul 2012 15:31:45 GMT Vary: Accept, Authorization Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
$ curl -i http://api.example.com/#{RESOURCE_URI} -H 'If-None-Match: "644b5b0155e6404a9cc4bd9d8b1ae730"' HTTP/1.1 304 Not Modified Cache-Control: public, max-age=60 Date: Thu, 05 Jul 2012 15:31:55 GMT Vary: Accept, Authorization ETag: "644b5b0155e6404a9cc4bd9d8b1ae730" Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
Last-Modified/If-Modified-Since要配合Cache-Control使用。
Etag/If-None-Match也要配合Cache-Control使用。
你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
浏览器第一次请求:
浏览器再次请求:
HTTP 请求方法
关于 HTTP Methods 语义的说明(http1.1):
OPTIONS
用于获取资源支持的所有 HTTP 方法HEAD
用于只获取请求某个资源返回的头信息GET
用于从服务器获取某个资源的信息200 OK
POST
用于创建新资源201 Created
PUT
用于完整的替换资源或者创建指定身份的资源,比如创建 id 为 123 的某个资源201 Created
200 OK
PATCH
用于局部更新资源200 OK
DELETE
用于删除某个资源204 No Content
状态码
请求成功
GET
成功POST
成功;创建完成后响应头中应该携带头标Location
,指向新建资源的地址PATCH
,DELETE
成功重定向
重定向的新地址都需要在响应头
Location
中返回GET
方法进行请求。比如在创建已经被创建的资源时,可以返回303
条件请求
客户端错误
403 Forbidden
。如果请求里有Authorization
头,那么必须返回一个WWW-Authenticate
头Allow
头,内容为对该资源有效的 HTTP 方法Content-Type
中声明格式名称404 Not Found
POST
或者PUT
请求的消息实体过大服务端错误
Retry-After
头用以标明这个延迟时间(内容可以为数字,单位为秒;或者是一个 HTTP 协议指定的时间格式)。如果没有给出这个Retry-After
信息,那么客户端应当以处理 500 响应的方式处理它。501
与405
的区别是:405
是表示服务端不允许客户端这么做,501
是表示客户端或许可以这么做,但服务端还没有实现这个功能错误处理
在调用接口的过程中,可能出现下列几种错误情况:
服务器维护中,
503
状态码发送了无法转化的请求体,
400
状态码服务到期(比如付费的增值服务等),
403
状态码因为某些原因不允许访问(比如被 ban ),
403
状态码权限不够,
403
状态码需要修改的资源不存在,
404
状态码缺少了必要的头信息,
428
状态码发送了非法的资源,
422
状态码所有的
error
哈希表都有resource
,field
,code
字段,以便于定位错误,code
字段则用于表示错误类型:invalid
: 某个字段的值非法,接口文档中会提供相应的信息required
: 缺失某个必须的字段not_exist
: 说明某个字段的值代表的资源不存在already_exist
: 发送的资源中的某个字段的值和服务器中已有的某个资源冲突,常见于某些值全局唯一的字段,比如 @ 用的用户名(这个错误我有纠结,因为其实有 409 状态码可以表示,但是在修改某个资源时,很一般显然请求中不止是一种错误,如果是 409 的话,多种错误的场景就不合适了)数据缓存
大部分接口应该在响应头中携带
Last-Modified
,ETag
,Vary
,Date
信息,客户端可以在随后请求这些资源的时候,在请求头中使用If-Modified-Since
,If-None-Match
等请求头来确认资源是否经过修改。如果资源没有进行过修改,那么就可以响应
304 Not Modified
并且不在响应实体中返回任何内容。Last-Modified/If-Modified-Since
Last-Modified/If-Modified-Since要配合Cache-Control使用。
Etag/If-None-Match
Etag/If-None-Match也要配合Cache-Control使用。
既生Last-Modified何生Etag?
你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
浏览器第一次请求:
浏览器再次请求: