跳到主要内容

15. 状态码

15. 状态码

响应的状态码 (status code) 是一个三位整数代码, 用于描述请求的结果和响应语义, 包括请求是否成功以及响应中封装了什么内容 (如果有). 所有有效状态码都在 100 到 599 的闭区间内.

状态码的第一位定义响应类别. 后两位没有任何分类作用. 第一位有五种取值:

  • 1xx (Informational): 请求已收到, 继续处理
  • 2xx (Successful): 请求已成功接收, 理解并接受
  • 3xx (Redirection): 需要采取进一步操作才能完成请求
  • 4xx (Client Error): 请求包含错误语法或无法被满足
  • 5xx (Server Error): 服务器未能满足一个表面上有效的请求

HTTP 状态码是可扩展的. 客户端不需要理解所有已注册状态码的含义, 尽管这种理解显然是可取的. 但是, 客户端必须理解任何状态码由第一位指示的类别, 并将无法识别的状态码视为等价于该类别的 x00 状态码.

例如, 如果客户端收到无法识别的状态码 471, 它可以从第一位看出其请求存在某种问题, 并像收到 400 (Bad Request) 状态码一样处理该响应. 响应消息通常会包含一个解释该状态的表示.

100..599 范围之外的值无效. 实现经常使用该范围之外的三位整数值 (即 600..999) 在内部传达非 HTTP 状态 (例如库错误). 收到带有无效状态码响应的客户端应该像处理 5xx (Server Error) 状态码一样处理该响应.

单个请求可以有关联的多个响应: 零个或多个状态码位于 "informational" (1xx) 范围内的 "interim" (非最终) 响应, 后跟恰好一个状态码位于其他范围内的 "final" (最终) 响应.

15.1. 状态码概述

下面列出的状态码由本规范定义. 此处列出的原因短语 (reason phrase) 只是建议, 可以替换为本地等价项, 也可以完全省略, 而不会影响协议.

被定义为可启发式缓存的状态码响应 (例如本规范中的 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414 和 501), 除非方法定义或显式缓存控制 [CACHING] 另有指示, 可以由缓存通过启发式过期方式复用; 所有其他状态码都不可启发式缓存.

本规范范围之外还定义了其他用于 HTTP 的状态码. 所有此类状态码都应当按照 Section 16.2 所述注册到 "Hypertext Transfer Protocol (HTTP) Status Code Registry".

15.2. 信息性 1xx

1xx (Informational) 状态码类别表示一个 interim (临时) 响应, 用于在完成所请求的操作并发送 final (最终) 响应之前传达连接状态或请求进度. 由于 HTTP/1.0 未定义任何 1xx 状态码, 服务器不得向 HTTP/1.0 客户端发送 1xx 响应.

1xx 响应由头部区段结束而终止; 它不能包含内容或 trailers.

客户端必须能够解析在 final 响应之前收到的一个或多个 1xx 响应, 即使客户端并未期待这些响应. 用户代理可以忽略意外的 1xx 响应.

代理必须转发 1xx 响应, 除非该 1xx 响应是代理自身请求生成的. 例如, 如果代理在转发请求时添加了 "Expect: 100-continue" 头字段, 则它不需要转发对应的 100 (Continue) 响应.

15.2.1. 100 Continue

100 (Continue) 状态码表示请求的初始部分已经收到, 且尚未被服务器拒绝. 服务器打算在完整收到请求并对其采取行动之后发送 final 响应.

当请求包含带有 100-continue expectation 的 Expect 头字段时, 100 响应表示服务器希望接收请求内容, 如 Section 10.1.1 所述. 客户端应当继续发送请求并丢弃 100 响应.

如果请求未包含带有 100-continue expectation 的 Expect 头字段, 客户端可以直接丢弃此 interim 响应.

15.2.2. 101 Switching Protocols

101 (Switching Protocols) 状态码表示服务器理解并愿意遵从客户端通过 Upgrade 头字段 (Section 7.8) 发出的请求, 即更改此连接上使用的应用协议. 服务器必须在响应中生成 Upgrade 头字段, 指示此响应之后将生效的协议.

假定服务器只会在有利时才同意切换协议. 例如, 切换到较新版本的 HTTP 可能比旧版本更有利; 在交付使用实时同步特性的资源时, 切换到实时同步协议也可能有利.

15.3. 成功 2xx

2xx (Successful) 状态码类别表示客户端请求已被成功接收, 理解并接受.

15.3.1. 200 OK

200 (OK) 状态码表示请求已成功. 200 响应中发送的内容取决于请求方法. 对于本规范定义的方法, 内容的预期含义可以概括为:

请求方法响应内容是以下内容的表示
GET目标资源
HEAD目标资源, 类似 GET, 但不传输表示数据
POST操作的状态或从操作获得的结果
PUT, DELETE操作的状态
OPTIONS目标资源的通信选项
TRACE返回 trace 的服务器所收到的请求消息

除对 CONNECT 的响应外, 200 响应预期包含消息内容, 除非消息定帧明确指示内容长度为零. 如果请求的某些方面表明成功时偏好无内容, 源服务器应当改为发送 204 (No Content) 响应. 对于 CONNECT, 没有内容, 因为成功结果是一个隧道, 该隧道在 200 响应头部区段之后立即开始.

200 响应可启发式缓存, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

在对 GET 或 HEAD 的 200 响应中, 源服务器应该为选定表示发送任何可用的验证器字段 (Section 8.8), 优先发送强 entity tag 和 Last-Modified 日期.

在对状态变更方法的 200 响应中, 响应中发送的任何验证器字段 (Section 8.8) 都传达成功应用请求语义后形成的新表示的当前验证器. 注意, PUT 方法 (Section 9.3.4) 有可能阻止发送此类验证器的附加要求.

15.3.2. 201 Created

201 (Created) 状态码表示请求已被满足, 并导致创建了一个或多个新资源. 由该请求创建的主要资源由响应中的 Location 头字段标识; 如果未收到 Location 头字段, 则由目标 URI 标识.

201 响应内容通常会描述并链接到已创建的资源. 响应中发送的任何验证器字段 (Section 8.8) 都传达由该请求创建的新表示的当前验证器. 注意, PUT 方法 (Section 9.3.4) 有可能阻止发送此类验证器的附加要求.

15.3.3. 202 Accepted

202 (Accepted) 状态码表示请求已被接受处理, 但处理尚未完成. 该请求最终可能会被执行, 也可能不会被执行, 因为实际处理时可能会不允许执行它. HTTP 没有从异步操作重新发送状态码的机制.

202 响应有意不作承诺. 其目的是允许服务器接受请求并交由其他进程处理 (也许是每天只运行一次的批处理进程), 而不要求用户代理到服务器的连接持续到该进程完成. 随此响应发送的表示应当描述请求的当前状态, 并指向 (或嵌入) 一个状态监视器, 以便向用户估计请求何时会被满足.

15.3.4. 203 Non-Authoritative Information

203 (Non-Authoritative Information) 状态码表示请求成功, 但是封装内容已被转换代理 (Section 7.7) 从源服务器的 200 (OK) 响应修改. 该状态码允许代理在应用转换时通知接收方, 因为这种认知可能影响之后关于内容的决策. 例如, 未来针对该内容的缓存验证请求可能只适用于同一请求路径 (经过相同代理).

203 响应可启发式缓存, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.3.5. 204 No Content

204 (No Content) 状态码表示服务器已成功满足请求, 且响应内容中没有附加内容要发送. 响应头字段中的元数据指向应用所请求的操作之后的目标资源及其选定表示.

例如, 如果对 PUT 请求的响应收到 204 状态码且响应包含 ETag 字段, 则 PUT 成功, ETag 字段值包含该目标资源新表示的 entity tag.

204 响应允许服务器指示操作已成功应用于目标资源, 同时暗示用户代理不需要离开其当前 "document view" (如果有). 服务器假定用户代理会按照自身界面向用户提供某种成功指示, 并将响应中的任何新元数据或更新后的元数据应用到其活动表示.

例如, 204 状态码常用于与 "save" 操作对应的文档编辑接口, 使正在保存的文档仍可供用户编辑. 它也经常用于预期自动化数据传输很常见的接口, 例如分布式版本控制系统.

204 响应由头部区段结束而终止; 它不能包含内容或 trailers.

204 响应可启发式缓存, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.3.6. 205 Reset Content

205 (Reset Content) 状态码表示服务器已满足请求, 并希望用户代理将导致请求发送的 "document view" 重置为从源服务器收到时的原始状态.

该响应旨在支持一个常见的数据录入用例: 用户收到支持数据录入的内容 (表单, 记事本, 画布等), 在其中输入或操作数据, 使已输入数据通过请求提交, 然后数据录入机制被重置以便下一次录入, 让用户能够轻松开始另一次输入操作.

由于 205 状态码暗示不会提供附加内容, 服务器不得在 205 响应中生成内容.

15.3.7. 206 Partial Content

206 (Partial Content) 状态码表示服务器正通过传输选定表示的一个或多个部分, 成功满足针对目标资源的范围请求.

支持范围请求 (Section 14) 的服务器通常会尝试满足所有被请求的范围, 因为发送较少数据很可能导致客户端再次请求剩余部分. 但是, 服务器可能出于自身原因只发送所请求数据的一个子集, 例如临时不可用, 缓存效率或负载均衡等. 由于 206 响应是自描述的, 客户端仍能理解只部分满足其范围请求的响应.

客户端必须检查 206 响应的 Content-Type 和 Content-Range 字段, 以确定封装了哪些部分以及是否需要附加请求.

如果对同一请求的 200 (OK) 响应本会发送 Date, Cache-Control, ETag, Expires, Content-Location 和 Vary, 则生成 206 响应的服务器必须生成这些头字段, 以及下面小节中要求的头字段.

206 响应中出现的 Content-Length 头字段表示此消息内容中的八位字节数, 通常不是选定表示的完整长度. 每个 Content-Range 头字段都包含关于选定表示完整长度的信息.

对带有 If-Range 头字段的请求生成 206 响应的发送方不应该生成所要求字段之外的其他表示头字段, 因为客户端已经有一个包含这些头字段的先前响应. 否则, 发送方必须生成对同一请求的 200 (OK) 响应本会发送的所有表示头字段.

206 响应可启发式缓存, 除非显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.3.7.1. 单个部分

如果正在传输单个部分, 生成 206 响应的服务器必须生成 Content-Range 头字段来描述选定表示中封装的范围, 并生成由该范围组成的内容. 例如:

HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif

... 26012 bytes of partial image data ...
15.3.7.2. 多个部分

如果正在传输多个部分, 生成 206 响应的服务器必须生成 Section 14.6 定义的 "multipart/byteranges" 内容, 以及包含 "multipart/byteranges" 媒体类型及其必需 boundary 参数的 Content-Type 头字段. 为了避免与单部分响应混淆, 服务器不得在多部分响应的 HTTP 头部区段中生成 Content-Range 头字段 (该字段会改为在每个部分中发送).

在 multipart 内容的每个主体部分头部区域中, 服务器必须生成一个 Content-Range 头字段, 对应于该主体部分所封装的范围. 如果选定表示在 200 (OK) 响应中本会有 Content-Type 头字段, 服务器应该在每个主体部分头部区域中生成同一个 Content-Type 头字段. 例如:

HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Length: 1741
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES

--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000

...the first range...
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 7000-7999/8000

...the second range
--THIS_STRING_SEPARATES--

请求多个范围时, 服务器可以合并任何重叠范围, 或合并间隙小于发送多个部分所需开销的范围, 而不考虑对应 range-spec 在收到的 Range 头字段中出现的顺序. 由于 "multipart/byteranges" 的每个部分之间典型开销约为 80 bytes, 具体取决于选定表示的媒体类型和所选 boundary 参数长度, 因此传输许多小的不相交部分可能不如传输整个选定表示高效.

服务器不得对单个范围请求生成 multipart 响应, 因为未请求多个部分的客户端可能不支持 multipart 响应. 但是, 如果请求了多个范围, 但只有一个范围可满足, 或合并后只剩一个范围, 服务器可以生成仅有单个主体部分的 "multipart/byteranges" 响应. 不能处理 "multipart/byteranges" 响应的客户端不得生成请求多个范围的请求.

生成 multipart 响应的服务器应该按照对应 range-spec 在收到的 Range 头字段中出现的顺序发送各部分, 排除被认为不可满足或已合并到其他范围中的范围. 收到 multipart 响应的客户端必须检查每个主体部分中出现的 Content-Range 头字段, 以确定该主体部分包含哪个范围; 客户端不能依赖收到与其请求相同的范围, 也不能依赖相同的顺序.

15.3.7.3. 组合部分

如果连接过早关闭或请求使用了一个或多个 Range 规约, 响应可能只传输表示的一个子范围. 经过若干次此类传输后, 客户端可能已收到同一表示的若干范围. 只有当这些范围共有同一个强验证器 (Section 8.8.1) 时, 才能安全地组合它们.

客户端收到针对目标资源 GET 请求的多个部分响应后, 如果这些响应共享同一个强验证器, 可以将它们组合为一个更大的连续范围.

如果最新响应是不完整的 200 (OK) 响应, 则该响应的头字段用于任何组合响应, 并替换匹配的已存储响应的头字段.

如果最新响应是 206 (Partial Content) 响应且至少一个匹配的已存储响应是 200 (OK), 则组合响应头字段由最新 200 响应的头字段组成. 如果所有匹配的已存储响应都是 206 响应, 则使用头字段最新的已存储响应作为组合响应头字段的来源, 但客户端必须使用新响应中 Content-Range 之外提供的其他头字段, 替换已存储响应中对应头字段的所有实例.

组合响应内容由新响应和所有匹配的已存储响应中的部分内容范围的并集组成. 如果该并集构成表示的完整范围, 则客户端必须像处理完整 200 (OK) 响应一样处理组合响应, 包括反映完整长度的 Content-Length 头字段. 否则, 客户端必须将这组连续范围作为以下之一处理: 如果组合响应是表示前缀, 则作为不完整的 200 (OK) 响应; 作为包含 "multipart/byteranges" 内容的单个 206 (Partial Content) 响应; 或作为多个 206 (Partial Content) 响应, 每个响应都有一个由 Content-Range 头字段指示的连续范围.

15.4. 重定向 3xx

3xx (Redirection) 状态码类别表示用户代理需要采取进一步操作才能满足请求. 重定向有几种类型:

  1. 指示此资源可能可在另一个 URI 获得的重定向, 该 URI 由 Location 头字段提供, 如状态码 301 (Moved Permanently), 302 (Found), 307 (Temporary Redirect) 和 308 (Permanent Redirect).
  2. 提供一组能够表示此资源的匹配资源供选择的重定向, 如 300 (Multiple Choices) 状态码.
  3. 重定向到由 Location 头字段标识的另一个资源, 该资源可以表示对请求的间接响应, 如 303 (See Other) 状态码.
  4. 重定向到先前存储的结果, 如 304 (Not Modified) 状态码.

Note: 在 HTTP/1.0 中, 状态码 301 (Moved Permanently) 和 302 (Found) 最初被定义为保留方法 ([HTTP/1.0], Section 9.3), 以匹配 CERN 的实现; 303 (See Other) 被定义为一种将方法改为 GET 的重定向. 但是, 早期用户代理在如何重定向 POST 请求上存在分歧: 是按照当时的规范重定向为 POST, 还是在重定向到不同站点时采用更安全的替代方案并改为 GET. 主流实践最终收敛为将方法改为 GET. 后来增加了 307 (Temporary Redirect) 和 308 (Permanent Redirect) [RFC7538], 用于无歧义地指示保留方法的重定向, 并且状态码 301 和 302 已调整为允许 POST 请求被重定向为 GET.

如果提供了 Location 头字段 (Section 10.2.2), 即使不理解具体状态码, 用户代理也可以自动将其请求重定向到 Location 字段值所引用的 URI. 对于 Section 9.2.1 定义的未被认定为安全的方法, 自动重定向需要谨慎执行, 因为用户可能不希望重定向不安全请求.

自动跟随重定向请求时, 用户代理应该重新发送原始请求消息, 并进行以下修改:

  1. 将目标 URI 替换为重定向响应的 Location 头字段值所引用的 URI, 该 URI 按照原始请求的目标 URI 解析.

  2. 移除由实现自动生成的头字段, 并根据新请求需要将它们替换为更新后的值. 这包括:

    1. 连接特定头字段 (见 Section 7.6.1),

    2. 客户端代理配置特定头字段, 包括但不限于 Proxy-Authorization,

    3. origin 特定头字段 (如果有), 包括但不限于 Host,

    4. 由实现的缓存添加的验证头字段 (例如 If-None-Match, If-Modified-Since), 以及

    5. 资源特定头字段, 包括但不限于 Referer, Origin, Authorization 和 Cookie.

  3. 在存在安全影响时, 考虑移除并非由实现自动生成的头字段 (即因调用上下文添加而出现在请求中的头字段); 这包括但不限于 Authorization 和 Cookie.

  4. 如果适用, 按照重定向状态码的语义改变请求方法.

  5. 如果请求方法已改为 GET 或 HEAD, 移除内容特定头字段, 包括但不限于 Content-Encoding, Content-Language, Content-Location, Content-Type, Content-Length, Digest, Last-Modified.

客户端应该检测并介入循环重定向 (即 "infinite" 重定向循环).

Note: 本规范的早期版本建议最多五次重定向 ([RFC2068], Section 10.3). 内容开发者需要知道, 某些客户端可能实现这种固定限制.

15.4.1. 300 Multiple Choices

300 (Multiple Choices) 状态码表示目标资源有多个表示, 每个表示都有自己的更具体标识符, 并且提供了替代项信息, 以便用户 (或用户代理) 可以通过将请求重定向到其中一个或多个标识符来选择首选表示. 换言之, 服务器希望用户代理参与响应式协商, 以选择最适合其需要的表示 (Section 12).

如果服务器有首选项, 服务器应该生成包含首选项 URI 引用的 Location 头字段. 用户代理可以使用 Location 字段值进行自动重定向.

对于 HEAD 之外的请求方法, 服务器应该在 300 响应中生成内容, 其中包含表示元数据和 URI 引用列表, 供用户或用户代理从中选择最偏好的一个. 如果用户代理理解所提供的媒体类型, 可以从该列表中自动选择. 本规范没有定义自动选择的具体格式, 因为 HTTP 试图保持与其内容定义正交. 实践中, 表示会以某种易于解析且被认为用户代理可接受的格式提供, 该格式由共享设计或内容协商决定, 或者采用某种常见接受的超文本格式.

300 响应是启发式可缓存的, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

Note: 300 状态码的原始提案定义 URI 头字段用于提供替代表示列表, 使其可用于 200, 300 和 406 响应, 并可在对 HEAD 方法的响应中传输. 但是, 由于缺乏部署且语法存在分歧, URI 以及后续提案 Alternates 都已从本规范中删除. 可以将该列表作为 Link 头字段值 [RFC8288] 来传达, 其中成员具有 "alternate" 关系, 但部署存在先有鸡还是先有蛋的问题.

15.4.2. 301 Moved Permanently

301 (Moved Permanently) 状态码表示目标资源已被分配新的永久 URI, 未来对该资源的任何引用都应当使用响应中封装的某个 URI. 服务器建议具有链接编辑能力的用户代理, 可以用服务器发送的新引用之一永久替换对目标 URI 的引用. 不过, 除非用户代理正在主动编辑引用 (例如正在创作内容), 连接受保护, 且源服务器是被编辑内容的可信权威, 否则该建议通常会被忽略.

服务器应该在响应中生成 Location 头字段, 其中包含新永久 URI 的首选 URI 引用. 用户代理可以使用 Location 字段值进行自动重定向. 服务器的响应内容通常包含简短的超文本说明, 其中有指向新 URI 的超链接.

Note: 出于历史原因, 用户代理可以将后续请求的方法从 POST 改为 GET. 如果不希望出现这种行为, 可以改用 308 (Permanent Redirect) 状态码.

301 响应是启发式可缓存的, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.4.3. 302 Found

302 (Found) 状态码表示目标资源临时位于另一个 URI. 由于重定向偶尔可能改变, 客户端应当继续使用目标 URI 发起未来请求.

服务器应该在响应中生成 Location 头字段, 其中包含不同 URI 的 URI 引用. 用户代理可以使用 Location 字段值进行自动重定向. 服务器的响应内容通常包含简短的超文本说明, 其中有指向不同 URI 的超链接.

Note: 出于历史原因, 用户代理可以将后续请求的方法从 POST 改为 GET. 如果不希望出现这种行为, 可以改用 307 (Temporary Redirect) 状态码.

15.4.4. 303 See Other

303 (See Other) 状态码表示服务器正在将用户代理重定向到 Location 头字段中的 URI 所指示的不同资源, 该资源旨在提供对原始请求的间接响应. 用户代理可以对该 URI 执行获取请求 (使用 HTTP 时为 GET 或 HEAD 请求), 该请求也可能被重定向, 并将最终结果作为对原始请求的回答呈现. 注意, Location 头字段中的新 URI 不被认为等价于目标 URI.

此状态码适用于任何 HTTP 方法. 它主要用于允许 POST 操作的输出将用户代理重定向到不同资源, 因为这样可以把对应 POST 响应的信息作为可单独标识, 可加入书签且可缓存的资源提供.

对 GET 请求的 303 响应表示源服务器没有可通过 HTTP 由服务器传输的目标资源表示. 不过, Location 字段值指向一个描述目标资源的资源, 因此对该其他资源发起获取请求可能得到对接收方有用的表示, 但并不暗示它表示原始目标资源. 关于什么可以被表示, 哪些表示是充分的, 以及什么可能是有用描述的问题, 都超出 HTTP 范围.

除对 HEAD 请求的响应外, 303 响应的表示应当包含简短的超文本说明, 其中有指向 Location 头字段所提供同一 URI 引用的超链接.

15.4.5. 304 Not Modified

304 (Not Modified) 状态码表示已收到条件 GET 或 HEAD 请求, 且如果不是条件求值为 false, 本应产生 200 (OK) 响应. 换言之, 服务器不需要传输目标资源的表示, 因为该请求表明发起条件请求的客户端已经有有效表示; 因此, 服务器将客户端重定向为像使用 200 (OK) 响应内容一样使用该已存储表示.

生成 304 响应的服务器必须生成以下头字段中那些在同一请求的 200 (OK) 响应中本应发送的字段:

  • Content-Location, Date, ETag, 和 Vary

  • Cache-Control 和 Expires (见 [CACHING])

由于 304 响应的目标是在接收方已有一个或多个缓存表示时最小化信息传输, 发送方不应该生成上面列出的字段之外的表示元数据, 除非该元数据用于指导缓存更新 (例如, 当响应没有 ETag 字段时 Last-Modified 可能有用).

缓存收到 304 响应时的要求定义在 [CACHING] 的 Section 4.3.4. 如果条件请求来自出站客户端, 例如有自身缓存的用户代理向共享代理发送条件 GET, 则代理应该将 304 响应转发给该客户端.

304 响应由头部区段结束而终止; 它不能包含内容或 trailers.

15.4.6. 305 Use Proxy

305 (Use Proxy) 状态码在本规范的先前版本中定义, 现已废弃 ([RFC7231] 的 Appendix B).

15.4.7. 306 (Unused)

306 状态码在本规范的先前版本中定义, 现已不再使用, 且该代码被保留.

15.4.8. 307 Temporary Redirect

307 (Temporary Redirect) 状态码表示目标资源临时位于另一个 URI, 且如果用户代理对该 URI 执行自动重定向, 不得改变请求方法. 由于重定向可能随时间改变, 客户端应当继续使用原始目标 URI 发起未来请求.

服务器应该在响应中生成 Location 头字段, 其中包含不同 URI 的 URI 引用. 用户代理可以使用 Location 字段值进行自动重定向. 服务器的响应内容通常包含简短的超文本说明, 其中有指向不同 URI 的超链接.

15.4.9. 308 Permanent Redirect

308 (Permanent Redirect) 状态码表示目标资源已被分配新的永久 URI, 未来对该资源的任何引用都应当使用响应中封装的某个 URI. 服务器建议具有链接编辑能力的用户代理, 可以用服务器发送的新引用之一永久替换对目标 URI 的引用. 不过, 除非用户代理正在主动编辑引用 (例如正在创作内容), 连接受保护, 且源服务器是被编辑内容的可信权威, 否则该建议通常会被忽略.

服务器应该在响应中生成 Location 头字段, 其中包含新永久 URI 的首选 URI 引用. 用户代理可以使用 Location 字段值进行自动重定向. 服务器的响应内容通常包含简短的超文本说明, 其中有指向新 URI 的超链接.

308 响应是启发式可缓存的, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

Note: 此状态码比其同类状态码年轻得多 (2014 年 6 月), 因而可能并非在所有地方都能被识别. 部署注意事项见 [RFC7538] 的 Section 4.

15.5. 客户端错误 4xx

4xx (Client Error) 状态码类别表示客户端似乎出错. 除对 HEAD 请求的响应外, 服务器应该发送一个表示, 其中包含对错误情况的解释, 并说明该情况是临时还是永久. 这些状态码适用于任何请求方法. 用户代理应该向用户显示所包含的任何表示.

15.5.1. 400 Bad Request

400 (Bad Request) 状态码表示服务器不能或不会处理该请求, 原因是某些被认为是客户端错误的情况 (例如格式错误的请求语法, 无效的请求消息定帧, 或欺骗性请求路由).

15.5.2. 401 Unauthorized

401 (Unauthorized) 状态码表示请求尚未被应用, 因为它缺少适用于目标资源的有效认证凭据. 生成 401 响应的服务器必须发送 WWW-Authenticate 头字段 (Section 11.6.1), 其中至少包含一个适用于目标资源的 challenge.

如果请求包含认证凭据, 则 401 响应表示这些凭据的授权已被拒绝. 用户代理可以使用新的或替换后的 Authorization 头字段 (Section 11.6.2) 重复该请求. 如果 401 响应包含与先前响应相同的 challenge, 且用户代理已经至少尝试过一次认证, 则用户代理应该向用户呈现所附表示, 因为其中通常包含相关诊断信息.

15.5.3. 402 Payment Required

402 (Payment Required) 状态码保留供未来使用.

15.5.4. 403 Forbidden

403 (Forbidden) 状态码表示服务器理解该请求, 但拒绝满足它. 希望公开说明请求为何被禁止的服务器, 可以在响应内容中描述原因 (如果有).

如果请求中提供了认证凭据, 服务器会认为这些凭据不足以授予访问权限. 客户端不应该使用相同凭据自动重复请求. 客户端可以使用新的或不同的凭据重复请求. 不过, 请求也可能因为与凭据无关的原因而被禁止.

希望"隐藏"被禁止的目标资源当前存在这一事实的源服务器, 可以改用 404 (Not Found) 状态码进行响应.

15.5.5. 404 Not Found

404 (Not Found) 状态码表示源服务器未找到目标资源的当前表示, 或不愿披露存在这样的表示. 404 状态码并不表明这种缺少表示的情况是临时还是永久; 如果源服务器知道 (大概通过某种可配置手段) 该情况可能是永久性的, 则优先使用 410 (Gone) 状态码, 而不是 404.

404 响应是启发式可缓存的, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.5.6. 405 Method Not Allowed

405 (Method Not Allowed) 状态码表示源服务器知道 request-line 中收到的方法, 但目标资源不支持该方法. 源服务器必须在 405 响应中生成 Allow 头字段, 其中包含目标资源当前支持的方法列表.

405 响应是启发式可缓存的, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.5.7. 406 Not Acceptable

406 (Not Acceptable) 状态码表示, 根据请求中收到的主动协商头字段 (Section 12.1), 目标资源没有用户代理可接受的当前表示, 且服务器不愿提供默认表示.

服务器应该生成包含可用表示特征和对应资源标识符列表的内容, 用户或用户代理可以从中选择最合适的一项. 用户代理可以从该列表中自动选择最合适的选项. 不过, 如 Section 15.4.1 所述, 本规范没有定义此类自动选择的任何标准.

15.5.8. 407 Proxy Authentication Required

407 (Proxy Authentication Required) 状态码类似于 401 (Unauthorized), 但它表示客户端需要先对自身进行认证, 才能为此请求使用代理. 代理必须发送 Proxy-Authenticate 头字段 (Section 11.7.1), 其中包含适用于该请求所用代理的 challenge. 客户端可以使用新的或替换后的 Proxy-Authorization 头字段 (Section 11.7.2) 重复该请求.

15.5.9. 408 Request Timeout

408 (Request Timeout) 状态码表示服务器在其准备等待的时间内没有收到完整的请求消息.

如果客户端有正在传输中的未完成请求, 可以重复该请求. 如果当前连接不可用 (例如在 HTTP/1.1 中因为请求定界丢失), 将使用新连接.

15.5.10. 409 Conflict

409 (Conflict) 状态码表示由于与目标资源的当前状态冲突, 请求无法完成. 该代码用于用户可能能够解决冲突并重新提交请求的情况. 服务器应该生成包含足够信息的内容, 使用户能够识别冲突来源.

冲突最可能发生在对 PUT 请求的响应中. 例如, 如果使用了版本控制, 且被 PUT 的表示包含对资源的更改, 这些更改与较早的 (第三方) 请求所做更改冲突, 源服务器可能使用 409 响应来指示无法完成该请求. 在这种情况下, 响应表示很可能包含基于修订历史合并差异所需的信息.

15.5.11. 410 Gone

410 (Gone) 状态码表示目标资源在源服务器上不再可访问, 且这种情况可能是永久性的. 如果源服务器不知道或无法确定该情况是否永久, 则应当改用 404 (Not Found) 状态码.

410 响应主要旨在协助 Web 维护任务, 即通知接收方该资源有意不可用, 且服务器所有者希望移除指向该资源的远程链接. 这种事件常见于限时促销服务, 以及属于不再与源服务器站点相关个人的资源. 不必将所有永久不可用资源都标记为 "gone", 也不必将该标记保留任何时长, 这由服务器所有者自行决定.

410 响应是启发式可缓存的, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.5.12. 411 Length Required

411 (Length Required) 状态码表示服务器拒绝接受没有定义 Content-Length (Section 8.6) 的请求. 如果客户端添加包含请求内容长度的有效 Content-Length 头字段, 可以重复该请求.

15.5.13. 412 Precondition Failed

412 (Precondition Failed) 状态码表示请求头字段中给出的一个或多个条件在服务器测试时求值为 false (Section 13). 该响应状态码允许客户端对当前资源状态 (其当前表示和元数据) 设置前置条件, 从而在目标资源处于意外状态时阻止请求方法被应用.

15.5.14. 413 Content Too Large

413 (Content Too Large) 状态码表示服务器拒绝处理请求, 因为请求内容大于服务器愿意或能够处理的大小. 如果所用协议版本允许, 服务器可以终止该请求; 否则, 服务器可以关闭连接.

如果该情况是临时的, 服务器应该生成 Retry-After 头字段, 以指示这是临时情况以及客户端可以在何时重试.

15.5.15. 414 URI Too Long

414 (URI Too Long) 状态码表示服务器拒绝服务该请求, 因为目标 URI 长于服务器愿意解释的长度. 这种罕见情况通常只会在以下情形发生: 客户端错误地将 POST 请求转换为带有很长查询信息的 GET 请求, 客户端陷入无限重定向循环 (例如重定向 URI 前缀指向其自身后缀), 或服务器正在受到试图利用潜在安全漏洞的客户端攻击.

414 响应是启发式可缓存的, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.5.16. 415 Unsupported Media Type

415 (Unsupported Media Type) 状态码表示源服务器拒绝服务该请求, 因为内容采用了目标资源上此方法不支持的格式.

格式问题可能由请求指示的 Content-Type 或 Content-Encoding 导致, 也可能是直接检查数据的结果.

如果问题由不支持的内容编码导致, 应当使用 Accept-Encoding 响应头字段 (Section 12.5.3) 指示请求中本可接受哪些内容编码 (如果有).

另一方面, 如果原因是不支持的媒体类型, 可以使用 Accept 响应头字段 (Section 12.5.1) 指示请求中本可接受哪些媒体类型.

15.5.17. 416 Range Not Satisfiable

416 (Range Not Satisfiable) 状态码表示请求的 Range 头字段 (Section 14.2) 中的范围集合已被拒绝, 原因可能是所请求的范围没有一个可满足, 也可能是客户端请求了数量过多的小范围或重叠范围 (潜在的拒绝服务攻击).

每个范围单位都定义了自身范围集合可满足所需的条件. 例如, Section 14.1.2 定义了 bytes 范围集合可满足的条件.

对 byte-range 请求生成 416 响应的服务器应该生成 Content-Range 头字段, 指定所选表示的当前长度 (Section 14.4).

例如:

HTTP/1.1 416 Range Not Satisfiable
Date: Fri, 20 Jan 2012 15:41:54 GMT
Content-Range: bytes */47022

Note: 由于服务器可以自由忽略 Range, 许多实现会以 200 (OK) 响应返回整个所选表示. 部分原因是大多数客户端已准备好接收 200 (OK) 来完成任务 (虽然效率较低), 部分原因是客户端在收到完整表示之前可能不会停止发起无效范围请求. 因此, 即使 416 (Range Not Satisfiable) 响应最为合适, 客户端也不能依赖一定会收到它.

15.5.18. 417 Expectation Failed

417 (Expectation Failed) 状态码表示请求的 Expect 头字段 (Section 10.1.1) 中给出的 expectation 无法由至少一个入站服务器满足.

15.5.19. 418 (Unused)

[RFC2324] 是一篇 4 月 1 日 RFC, 讽刺了 HTTP 被滥用的各种方式; 其中一种滥用是定义了应用专用的 418 状态码, 该代码作为玩笑已被部署得足够多, 因而无法供未来任何用途使用.

因此, 418 状态码在 IANA HTTP Status Code Registry 中被保留. 这表示该状态码目前不能分配给其他应用. 如果未来情况需要使用它 (例如 4NN 状态码耗尽), 它可以被重新分配给另一用途.

15.5.20. 421 Misdirected Request

421 (Misdirected Request) 状态码表示请求被定向到一个无法或不愿为目标 URI 生成权威响应的服务器. 源服务器 (或代表源服务器行事的网关) 发送 421, 用于拒绝与服务器已配置 origin (Section 4.3.1) 不匹配, 或与接收请求所经连接上下文 (Section 7.4) 不匹配的目标 URI.

收到 421 (Misdirected Request) 响应的客户端可以通过不同连接重试请求, 无论请求方法是否幂等, 例如使用专用于目标资源 origin 的新连接, 或通过替代服务 [ALTSVC].

代理禁止生成 421 响应.

15.5.21. 422 Unprocessable Content

422 (Unprocessable Content) 状态码表示服务器理解请求内容的内容类型 (因此 415 (Unsupported Media Type) 状态码不适用), 且请求内容语法正确, 但无法处理其中包含的指令. 例如, 如果 XML 请求内容包含格式良好 (即语法正确) 但语义错误的 XML 指令, 可以发送此状态码.

15.5.22. 426 Upgrade Required

426 (Upgrade Required) 状态码表示服务器拒绝使用当前协议执行请求, 但在客户端升级到不同协议后可能愿意执行. 服务器必须在 426 响应中发送 Upgrade 头字段, 以指示所需协议 (Section 7.8).

示例:

HTTP/1.1 426 Upgrade Required
Upgrade: HTTP/3.0
Connection: Upgrade
Content-Length: 53
Content-Type: text/plain

This service requires use of the HTTP/3.0 protocol.

15.6. 服务器错误 5xx

5xx (Server Error) 状态码类别表示服务器知道自己出错, 或无法执行所请求的方法. 除响应 HEAD 请求外, 服务器应该发送一个表示, 其中解释错误情况以及该情况是临时还是永久. 用户代理应该向用户显示任何所附表示. 此类状态码适用于任何请求方法.

15.6.1. 500 Internal Server Error

500 (Internal Server Error) 状态码表示服务器遇到意外情况, 导致其无法满足请求.

15.6.2. 501 Not Implemented

501 (Not Implemented) 状态码表示服务器不支持满足请求所需的功能. 当服务器不识别请求方法且无法为任何资源支持该方法时, 这是适当响应.

501 响应是启发式可缓存的, 除非方法定义或显式缓存控制另有指示 (见 [CACHING] 的 Section 4.2.2).

15.6.3. 502 Bad Gateway

502 (Bad Gateway) 状态码表示服务器作为网关或代理时, 在试图满足请求期间从其访问的入站服务器收到了无效响应.

15.6.4. 503 Service Unavailable

503 (Service Unavailable) 状态码表示服务器当前由于临时过载或计划维护而无法处理请求, 这种情况很可能在一段延迟后缓解. 服务器可以发送 Retry-After 头字段 (Section 10.2.3), 建议客户端在重试请求前等待适当时间.

Note: 503 状态码的存在不意味着服务器在过载时必须使用它. 某些服务器可能只是拒绝连接.

15.6.5. 504 Gateway Timeout

504 (Gateway Timeout) 状态码表示服务器作为网关或代理时, 未能从完成请求所需访问的上游服务器及时收到响应.

15.6.6. 505 HTTP Version Not Supported

505 (HTTP Version Not Supported) 状态码表示服务器不支持或拒绝支持请求消息中使用的 HTTP 主版本. 如 Section 2.5 所述, 服务器正在表明, 除了此错误消息外, 它无法或不愿使用与客户端相同的主版本完成请求. 服务器应该为 505 响应生成一个表示, 描述为何不支持该版本以及该服务器支持哪些其他协议.