分类
RFC 业界标准 基础知识 神奇的互联网

超文本传输协议(HTTP)中的响应状态码

本文内容评论 RFC 7231 第六章节

超文本传输协议(HTTP)的有趣之处在于,对于客户端向服务器发送的任意有效的请求,服务器都会做出响应。在这些响应报文中,包含了一组由三位数字组成的状态码,被称为响应状态码(Response Status Code),以表示服务器理解、尝试执行客户端所发出请求的结果。我们熟悉的 404(找不到网页)就是标准中定义的响应状态码之一。在本文中,我们首先回顾 HTTP RFC 标准中对于响应状态码的相关定义,然后对标准中定义的常见响应状态码给出解释。

用户使用诸如浏览器等通过 HTTP 协议访问网络的工具,被统称为“客户代理”(User Agent)程序:这些程序在遵循互联网标准的前提下,代替用户向对端服务器发送 HTTP 请求,并同样按照规定处理来自服务器的各种可能的响应。除此之外,HTTP 协议也被广泛地用于应用程序接口(Application Programming Interface,API)的设计中——一些开发者依赖被称为表现层状态转换(RESTful)风格的接口进行操作。然而,接口的设计者常会误用或滥用 HTTP 响应状态码,这会对调用接口程序的设计造成困扰。对于任何层次的开发者来说,了解 HTTP 协议中的常见响应状态码的含义都是重要的。

一张来自网络的搞笑图片,描述了客户端向服务器传递状态码为 200 的报文时,报文内容中包含 status code(状态码)字段,且值为 404
图片来自网络创作,描述了应用程序接口(API)的开发者滥用表示请求成功的状态码(200 OK)以表示所有请求状态的行为

HTTP RFC 标准将服务器可能返回的响应按照类型进行了分类。在网络服务器中返回的像 404(找不到网页)、500(服务器错误)以及 200(正常)的响应状态码中,第一位数字即表示响应的种类。RFC 标准中一共定义了五大类型的响应状态:

  • 1xx(信息类):表明请求已收到,正在处理
  • 2xx(成功):请求被成功接收、理解并接受
  • 3xx(重定向):为完成该请求需进行更多操作
  • 4xx(客户端错误):请求包含错误的语法或无法完成
  • 5xx(服务器错误):服务器无法完成看起来有效的请求

这样类似于 [1-5]xx 的响应状态码的设计为添加不同种具体的响应类型提供了拓展性:由于客户端不可能全部了解所有状态码的含义,当客户端收到一个未知的状态码时,只需要根据状态码的第一位数了解该响应状态的类别,以判断对端服务器对该请求的执行情况。状态码后两位数字与其分类是无关的。

另外,(包括大多数网页浏览器在内的)一些客户代理程序出于性能原因,被设计成能够缓存重复请求的响应结果。标准中规定,缓存包含以下状态码的响应内容是安全的:200、203、204、206、300、301、404、405、410、414 与 501。然而,客户端必须不能缓存一个包含未知响应状态码的响应。

RFC 标准 7232§47233§47235§3 中分别定义了一组响应状态码。而 RFC 7231§6 中汇总了这些状态码的含义。为便于概览,我们给出常见响应状态码含义的汇总表格(共 41 个)。在下文中,我们对于每一类的状态码以及常见的响应状态码给出详细解释。

响应状态码释义
100Continue
101Switching Protocols
200OK
201Created
202Accepted
203Non-Authoritative Information
204No Content
205Reset Content
206Partial Content
300Multiple Choices
301Moved Permanently
302Found
303See Other
304Not Modified
307Temporary Redirect
400Bad Request
401Unauthorized
403Forbidden
404Not Found
405Method Not Allowed
406Not Acceptable
407Proxy Authentication Required
408Request Timeout
409Conflict
410Gone
411Length Required
412Precondition Failed
413Payload Too Large
414URI Too Long
415Unsupported Media Type
416Range Not Satisfiable
417Expectation Failed
426Upgrade Required
500Internal Server Error
501Not Implemented
502Bad Gateway
503Service Unavailable
504Gateway Timeout
505HTTP Version Not Supported
上表是根据 RFC 7231§6 整理的常见的响应状态码;完整的响应状态码列表由互联网号码分配局(Internet Assigned Numbers Authority,IANA)维护,请见此处

信息类状态码 – 1xx

1xx(信息类)响应状态码用于在完成所请求的动作以至发送最终的响应之前发送一个表示通信连接状态、或者请求进度的临时响应。由于表示请求还没有处理完,这种类型的响应不应该包含响应载荷,而应在向客户端发送完响应头部信息后以一个空行作为终止。

响应载荷(有时也称“响应内容体”)是 HTTP 响应数据包的组成部分,HTTP 响应数据包一般由响应头部与响应载荷(内容)两部分组成。

虽然这种情况已经比较罕见,不过在早先的 HTTP/1.0 标准中,并没有定义 1xx 类别的状态码,所以服务器不应该向一个仅支持 HTTP/1.0 的客户端发送这种类型的响应数据包。

由于客户端并不能预期服务器关于处理其请求的状态,所以用户代理程序(客户端)可能会在收到表示最终状态的响应前收到一个或多个 1xx 类别的信息类状态码。客户端应当设计为可以安全忽略这些并非代表最终状态的响应状态码。

RFC 标准要求,如果 HTTP 服务器充当代理服务器,则除了代理服务器本身要求对端服务器进行 1xx 响应的情况外,代理服务器必须将 1xx 类型响应原样转发至客户端。

100 – Continue(继续)

100(Continue)响应状态码表示一个请求的初始部分已经被服务器收到并且未被拒绝,且服务器将在完全收到客户端传入的请求并且处理完毕后返回最终的响应数据。

cURL 等一些客户代理程序在向服务器传输大量数据的过程中,默认采用分块(分片)传输的策略:即通过发送多个独立的 HTTP 请求,在每个请求中传输其中部分数据。这是通过设置一个名为 Expect 头部来实现的。

Expect 头用于向服务器表明为了完成请求,其应当满足的期望。对于该头部,标准中目前定义的取值为 Expect: 100-continue,而服务器可以用 100 或者 417(Expectation Failed)作为响应,后者代表服务器无法满足期望。

MDN Web Docs | Expect – HTTP

当请求中包含 Expect: 100-continue 头部时,服务器返回 100(Continue)响应即意味着服务器希望继续接收来自客户端的响应载荷。目前除了 cURL 等客户代理程序以外,主流浏览器均不会主动向服务器发送该头部。

101 – Switching Protocols(切换协议)

101(Switching Protocols)响应状态码表示服务器理解并期望完成客户端通过 Upgrade 头域所发送的请求,且在后续连接过程中更改应用层的协议。根据标准,服务器必须于响应数据包中提供 Upgrade 头,以表示在 101 响应的空行结束后立刻切换至何种协议。

这种响应状态码用于当客户端请求将目前的协议(HTTP)切换为一个新的、不相容的协议时产生。借助这一技术,连接可以以常用的协议启动(如 HTTP/1.1),随后再升级到 HTTP/2.0 甚至是 WebSockets

它假设服务器只接受切换至对其更有利的协议。比如,切换至新版本的 HTTP 协议明显有利。切换至实时的、同步的协议会在传输特定的资源时更有利。

处理成功类状态码 – 2xx

2xx(处理成功类)响应状态码表示服务器成功收到、理解并接受来自客户端的请求。

200 – OK

这是最常见的 HTTP 响应状态码之一。200(OK)状态码简单地表示请求处理成功:当用户在浏览器中键入网址,并且成功地加载对应的页面时,对端服务器一般会返回该状态码表示请求成功。而其他情况下,这种来自服务器表示成功的响应并不一定包含响应正文(响应载荷),这具体取决于客户端是通过何种 HTTP 方法向服务器发送请求的:

客户端请求的 HTTP 方法响应载荷的处理方式
GET返回客户端所请求资源的表示(比如网页、音频等)
HEAD与 GET 一致,但并不包含这种“表示”的内容数据
POST返回所执行操作的表示或者相关结果
PUTDELETE返回对于给定操作的状态表示
OPTIONS返回对于连接参数与选项的表示
TRACE返回目标服务器收到所请求的消息的表示

除响应 CONNECT 的请求外,一个 200 响应总应包含响应载荷部分,即使响应正文部分为零长度。如果服务器确需发送一个不包含响应载荷部分的、表示请求成功的响应,则应考虑发送 204(No Content)响应状态码。对于 CONNECT 请求的响应,由于成功处理这种类型的请求导致建立一个可用的新隧道,所以不应在 200 请求后再包含响应正文。

202 – Accepted(接受)

202(Accepted)响应状态码表示请求被接受并处理,但尚未处理完成。用户发送的请求可能最终会生效,也可能不会生效。不过由于 HTTP 协议的特性,服务器在处理完成请求后无法异步地再向客户端通知其请求处理的最终状态(成功与否)。

202 请求被刻意设计为具有非承诺性的,也就是说,这种方式允许服务器接受来自其他进程的相关请求(特别比如是像每天执行一次的批处理脚本),而无需这些用户代理程序一直与服务器保持连接直至请求处理完成。RFC 标准中指导对于此种类型的响应,服务器应当在响应正文中随附一个状态指示器(可能是一个 URI 地址),客户端可以通过该指示器了解请求的处理状况。

203 – Non-Authoritative Information(非权威信息)

203(Non-Authoritative Information)响应状态码表示请求成功,但随附的响应载荷(响应正文)被中间的代理节点从源服务器发送的原始 200 响应中更改了。这个状态码其实提供了一种机制,即允许代理在进行了转换操作时通知接收者,因为这种转换行为也许会影响后续对内容的处理方式。

203 响应状态码与 214(Transformation Applied)警告码类似,后者的优势是适用于任何响应状态码中。

214(Transformation Applied)警告码是附带在响应头中的 Warning 头部的一种信息,表示本次响应提供的正文经第三方(如代理服务器)转换。

RFC 7234§5.5

204 – No Content(无内容)

204(No Content)响应状态码表示服务器已经成功处理完请求,但在响应载荷中无更多信息可提供。在响应内容的头部中已经提供了能够定位到目标资源的元信息以及所请求的操作执行完成之后给定的状态表示。

举个例子,如果收到了一个 PUT 请求对应的 204 响应并且响应内容中包含一个 ETag 头部字段,则 PUT 请求被成功执行,且随附的 ETag 字段表示对于新建的目标资源的实体标签(Entity Tag)表示。

204 响应允许服务器指明对目标资源所请求的动作被成功执行,且假定客户端无需遍历资源的“文档视图”(如果有)。服务器假定用户代理程序将会向用户提供关于操作执行成功的指示,且根据响应内容中添加或更新的元信息应用于资源的最新表示。

比如,204 状态码常用于文档编辑中的“保存”按钮,当用户执行保存操作时,文档编辑界面仍允许用户继续执行编辑操作。这种状态码也经常被用于自动分布式数据传输的界面中,比如分布式版本控制系统。

204 状态码在响应头部的空行后结束,因为其不能包含消息体内容(载荷部分)。

205 – Reset Content(重置内容)

205(Reset Content)响应状态码表示服务器完成给定的请求且期望用户代理程序重置所谓“文档视图”。即希望客户端将导致发送请求的“文档视图”重置为从原始服务器接收到的状态。

该响应旨在支持一种常见的数据录入用例,即用户接收到支持数据录入的内容(表单、记事本、画布等),在该空间中输入或操作数据,使输入的数据在请求中提交,然后为下一次输入重置数据录入机制,以便用户可以轻松地发起另一个输入操作。

由于 205 状态码意味着不会提供额外的内容,所以服务器必须不在 205 响应中生成有效载荷。 换句话说,服务器必须对 205 响应做以下操作之一:

  • 通过包含一个值为 0Content-Length 头字段来指示响应的零长度体
  • 通过包含一个值为 chunkedTransfer-Encoding 头字段和一个由零长度的单一块组成的消息体来指示响应的零长度有效载荷,或者
  • 在发送结束头部分的空行后立即关闭连接

重定向类状态码 – 3xx

3xx(重定向类)响应状态码表示为使用户代理程序完成所需操作需要执行一些额外动作。如果提供了 Location 域,则用户代理程序可以自动重定向请求到 Location 字段所指示的 URI 中,即便客户端可能无法理解给定的响应状态码是什么。由于这种自动重定向的行为根据所请求方法的不同并不一定是安全的,所以用户也许不希望对于非安全请求执行自动重定向操作。

存在以下几种重定向:

  1. 在状态码 301(Moved Permanently)、302(Found)以及 307(Temporary Redirect)的情况下,表示由于目标资源可能位于另一个 URI 上,而重定向;
  2. 在状态码 300(Multiple Choices)的情况下,表示从多个与原始请求匹配的资源的表示中选择一个;
  3. 在状态码 303(See Other)的情况下,表示根据 Location 域的指示重定向到另一个不同的资源,该资源是所请求资源的间接表示;
  4. 在状态码 304(Not Modified)的情况下,重定向至先前已经缓存的结果上;

需要注意,在 HTTP/1.0 中,响应状态码 301(Moved Permanently)以及 302(Found)被定义为第一类重定向。早期的用户代理程序在应用于重定向目标的方法是与原始请求相同还是重写为 GET 的问题上存在分歧。虽然 HTTP 最初为 301 和 302 定义了前一种语义(以匹配其在 CERN 的原始实现),并为303(See Other)定义了匹配后一种语义,但主流实践逐渐将 301 和 302 也趋向于后一种语义。HTTP/1.1 的第一次修订版增加了 307(Temporary Redirect)来表示前一种语义,而没有受到分歧实践的影响。十多年后,大多数用户代理仍在为 301 和 302 做方法重写,因此,本规范使该行为在原始请求是 POST 时符合。

客户端应当检测并干预循环重定向的问题。在 RFC 2068 这个较早的标准中,曾推荐客户端程序跟踪不超过五次重定向。开发者需要注意一些客户端程序仍遵循着这一限制。

300 – Multiple Choices(多重选择)

300(Multiple Choices)响应状态码表示目标资源有一种以上的表示,每个表示都有自己的更具体的标识符,并且提供了关于备选方案的信息,以便用户(或用户代理)可以通过将其请求重定向到一个或多个标识符来选择首选的表示。 换句话说,服务器希望用户代理进行被动的协商,以选择最适合其需要的表示。

如果服务器有一个推荐选项,则服务器应当生成一个包含推荐资源 URI 的 Location 域。这样,用户代理程序也许会根据 Location 域的指示自动进行重定向。

对于除 HEAD 以外的其他请求,服务器应当在包含 300 响应状态码的响应载荷中附带能够让用户或用户代理程序做出选择的反应资源的元信息以及 URI 的列表。用户代理程序也许能够从列表中自动选择其能够理解的格式的资源。对于自动选择的指定格式并非由 RFC 标准规定,因为 HTTP 试图保持对于其载荷定义的正交性(Orthogonal)。在实践中,这些表示将以容易被用户代理程序所接受的简单格式而提供,或许会是基于同一种统一的设计或者协议协商,又或者是以普遍能够接受的超文本格式提供。

在计算机领域中,我们称一个系统与另一个系统保持正交,即两者之间的任何改动均不会对另一个系统造成影响。

301 – Moved Permanently(被永久移动)

301(Moved Permanently)响应状态码表示所请求的目标资源已经被分配到一个新的统一资源标识符(URI)中,且未来任何访问到此资源的路径将使用随附的 URIs。拥有链接自动编辑能力的客户端将能自动更新这些链接地址至由服务器发送的一个或多个新地址。

服务器应当在响应的 Location 头域中生成能够访问到资源的推荐的新 URI。用户代理程序也许能够使用 Location 域中的信息执行自动重定向。来自服务器的响应载荷通常包含一个链接至新 URI 的超文本信息。

注意,由于历史性的原因,用户代理程序也许会将随后的请求方法由 POST 改为 GET;如果不希望该行为发生,则应当使用 307(Temporary Redirect)响应状态码。

302 – Found(已找到)

302(Found)响应状态码表示目标资源临时属于另一个不同的 URI。因为这种重定向也许之后会发生更改,所以客户端应当使用目前请求的这个 URI 执行未来的请求。

服务器应当在响应的 Location 头域中生成能够访问到资源的推荐的新 URI。用户代理程序也许能够使用 Location 域中的信息执行自动重定向。来自服务器的响应载荷通常包含一个链接至新 URI 的超文本信息。

注意,由于历史性的原因,用户代理程序也许会将随后的请求方法由 POST 改为 GET;如果不希望该行为发生,则应当使用 307(Temporary Redirect)响应状态码。

303 – See Other(查看其他资源)

303(See Other)响应状态码表示服务器通过 Location 域中的 URI 引导用户代理程序重定向到另一个不同的资源,该资源是所请求资源的间接响应。用户代理程序应当向给定的 URI 重新发送一遍请求,并将最终的结果作为原始请求的结果。注意在 Location 域中的新的 URI 与一开始请求的 URI 并不一定等价。

该状态码可用于响应任意种类的 HTTP 方法,但其主要用于将来自客户端用于创建资源的 POST 请求引导至一个指定的(可能是新创建的)资源中,因为这样做可以以独立于原始请求的方式提供与 POST 请求相对应的信息,而这些信息可以以独立 URI 的方式被单独识别、收藏和缓存。

另一种含义发生于对 GET 请求进行的 303 状态码的响应,这种响应表明服务器没有所请求的目标资源的表示。然而,在响应的 Location 字段则引导用户代理程序跳转至另一个具有描述性的资源。而这个资源虽然不是所请求的原始目标资源,但包含了可能对接收者有用的表示。除了对 HEAD 请求的响应外,303 响应的表示应该包含一个简短的超文本说明,并带有一个超链接,指向在 Location 头域中提供的相同URI引用。

HTTP 协议中并未规定关于什么可以被表示、何种程度的表示是足够的,以及什么可能是有用的描述等问题。

307 – Temporary Redirect(临时重定向)

307(Temporary Redirect)响应状态码表示目标资源临时依赖另一个不同的 URI 访问,而用户代理程序必须保持原有的 HTTP 请求方法不变的情况下,以给定的 URI 进行自动重定向。因为重定向的地址可能随时发生变更,客户端在下次请求时还必须以原始 URI 进行请求。

服务器应当在响应的 Location 头域中生成能够访问到资源的推荐的新 URI。用户代理程序也许能够使用 Location 域中的信息执行自动重定向。来自服务器的响应载荷通常包含一个链接至新 URI 的超文本信息。

注意,这个状态码有点像 302(Found),不过不允许客户端在重定向时改变请求的 HTTP 方法。本方法也与 301(Moved Permanently)不等价——308(Permanent Redirect)用来表示资源永久移动至新地址,并且指导用户代理程序使用相同的 HTTP 动词进行访问。

客户端错误类状态码 – 4xx

4xx(客户端错误)类状态码表示客户端似乎出错了。除了响应 HEAD 请求以外,服务器应该发送一个包含错误情况的解释,以及说明它是暂时的还是永久的情况。这些状态码适用于任何请求方法。用户代理程序应当向用户显示这些错误信息。

400 – Bad Request(错误请求)

400(Bad Request)响应状态码表示服务器不能或不会处理该请求,原因是被认为是客户端的错误(例如,错误的请求语法、无效的请求信息框架或欺骗性的请求路由)。

403 – Forbidden(禁止访问)

403(Forbidden)响应状态码表示服务器理解了请求,但拒绝授权。服务器如果希望公开请求被禁止的原因,可以在响应有效载荷中描述该原因(如果有的话)。

如果在请求中提供了认证凭证,服务器认为这些凭证不足以授予访问。客户端不应该用相同的凭证自动重复请求。客户端可以用新的或不同的凭证重复请求。但是,请求可能会因为与凭证无关的原因(比如客户端所使用的 IP 地址池被封禁)而被禁止。

希望 “隐藏 “被禁止的目标资源的当前存在的源服务器可以用一个404(Not Found)状态来响应。

404 – Not Found(找不到网页)

404(Not Found)响应状态码表示源服务器没有找到目标资源的当前表示,或者不愿意透露目标资源存在。404 状态码并不表明这种缺乏表示是暂时的还是永久的;如果源服务器知道(大概是通过一些可配置的手段)这种情况可能是永久的,那么 410(Gone)状态码比 404 更受欢迎。

405 – Method Not Allowed(方法不允许)

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

该状态码与 501(Not Implemented)不同,后者表示服务器不了解所请求的 HTTP 方法是什么。

406 – Not Acceptable(不可接受)

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

服务器应当生成包含可用的表示特性和相应的资源标识符的列表的有效载荷,用户或用户代理可以从中选择最合适的表示特性。用户代理可以从该列表中自动选择最合适的选择。

408 – Request Timeout(请求超时)

408(Request Timeout)响应状态码表示服务器在准备等待的时间内没有收到完整的请求消息。服务器应该在响应中发送 “关闭 “连接选项,因为 408 意味着服务器已经决定关闭连接而不是继续等待。如果客户端有一个未完成的请求在传输中,客户端可以在一个新的连接上重复该请求。

409 – Conflict(冲突)

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

冲突最可能发生在响应 PUT 请求时。例如,如果正在使用版本管理,并且被 PUT 的表示包括对资源的更改,而这些更改与早期(第三方)请求所做的更改相冲突,那么源服务器可能会使用 409 响应来表示它不能完成请求。在这种情况下,响应表示可能会包含对根据修订历史合并差异有用的信息。

410 – Gone(被永久移动)

410(Gone)响应状态码表示在源服务器上已无法访问目标资源,而且这种情况可能是永久性的。如果源服务器不知道或没有设施来确定这种情况是否是永久性的,则应使用状态码 404(Not Found)来代替。

410 响应的主要目的是通过通知接收者该资源是故意不可用的,以及服务器所有者希望删除到该资源的远程链接来协助网站维护的任务。这种事件常见于限时、促销服务以及属于个人的资源不再与原服务器的网站相关联。没有必要将所有永久不可用的资源标记为 “消失”,也没有必要在任何时间内保持标记——这由服务器所有者自行决定。

411 – Length Required(需要长度)

411(Length Required)响应状态码表示服务器拒绝接受没有定义 Content-Length 的请求。客户端可以在请求消息中添加一个包含消息主体长度的Content-Length 头域而重新请求。

413 – Payload Too Large(载荷太大)

413(Payload Too Large)响应状态码表示服务器拒绝处理请求,因为请求的有效载荷大于服务器愿意或能够处理的范围。服务器可以关闭连接以防止客户端继续请求。

如果这种情况是暂时的,服务器应该生成一个 Retry-After 头域,以表明这是暂时的,以及在什么时间之后客户端可以再次尝试。

414 – URI Too Long(URI 过长)

414(URI Too Long)响应状态码表示服务器拒绝服务该请求,因为请求目标比服务器愿意解释的长度要长。这种罕见的情况只可能在以下情况下发生:客户端不适当地将 POST 请求转换为具有长查询信息的 GET 请求,客户端陷入重定向的 “黑洞”(例如,重定向的 URI 前缀指向自身的后缀),或者服务器受到客户端试图利用潜在安全漏洞的攻击。

415 – Unsupported Media Type(不支持的媒体类型)

415(Unsupported Media Type)响应状态码表示源服务器拒绝服务该请求,因为有效载荷的格式在目标资源上不受该方法支持。格式问题可能是源于请求中指明的 Content-TypeContent-Encoding ,或者是直接检查数据的结果。

417 – Expectation Failed(期望失败)

417(Expectation Failed)响应状态码表示请求的期望头字段中给出的期望不能被至少一个入站服务器满足。该响应状态码与 100(Continue)对应,详见响应状态码 100(Continue)的描述。

426 – Upgrade Required(需要升级)

426(Upgrade Required)响应状态码表示服务器拒绝使用当前协议执行请求,但在客户机升级到不同的协议后可能愿意这样做。 服务器必须在 426 响应中发送一个升级头字段,以指示所需的协议,就比如:

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

上述示例表示服务器请求 HTTP/3.0 协议。

服务器错误类状态码 – 5xx

5xx(服务器错误)类状态码表示服务器意识到自己出错了,或者无法执行所请求的方法。除了响应 HEAD 请求以外,服务器应该发送一个包含有关错误情况的解释,以及说明这种问题是暂时的还是永久的。用户代理程序(如浏览器)应当向用户显示这些信息。对于任何请求方法,均适用于这些响应状态码。

这一类状态码由于表明错误是由服务器端造成的,客户端不太可能通过自身的努力(例如转换请求方式等)避免这些问题。

500 – Internal Server Error(服务器内部错误)

500(Internal Server Error)响应状态码表示服务器遇到了意外情况,使其无法完成请求。对于应用程序接口的开发者来说,当执行代码时遇到意外中断时,所使用的 HTTP 框架通常会向接口的调用者发送 500 状态码的响应,以表明服务器内部错误。

501 – Not Implemented(尚未实现)

501(Not Implemented)响应状态码表示服务器不支持所请求的 HTTP 方法。当使用服务器不支持的 HTTP 方法请求资源时,服务器端会做出如此响应。比如,客户代理程序尝试对服务器上的资源执行 DELETE 方法,而服务器本身未实现该方法时。

RFC 标准中规定,服务器必须至少实现 GET 与 HEAD 方法。

该状态码与 405(Method Not Allowed)不同,后者表示服务器了解请求所使用的 HTTP 方法,但针对所请求的资源本身不支持该方法。

502 – Bad Gateway(网关错误)

502(Bad Gateway)响应状态码表示服务器在作为网关或代理时,在试图完成请求时收到了它访问的入站服务器的无效响应。

像 Cloudflare 这样的内容分发网络(Content Delivery Network,CDN)服务商,通过分布于多个地理位置的边缘服务器,向用户提供访问目标服务器的加速服务。然而,当目标服务器不可用时,边缘服务器由于亦无法访问到目标服务器,则会向用户返回 502 或 504(见下方)响应,以表示在边缘服务器正常的情况下,无法连接至源服务器。

503 – Service Unavailable(服务不可用)

503(Service Unavailable)响应状态码表示服务器当前由于请求数太多或由于本身的维护行为导致无法处理目前的请求。比如,当同时打开了太多位于同一个网站中的页面时,服务器很可能对有的页面返回该状态码。再比如使用自动化程序请求某一个页面时,服务器可能对客户代理程序的请求频率进行限制,此时超出配额的链接请求即可能返回 503 状态码。

通常来讲,服务器返回该状态码表示其本身不可用的状态将在一定时间后得到缓解。客户端也许可以根据服务器响应头中的 Retry-After 头字段判断何时再请求合适。但该状态码并不意味着服务器在超载时必须使用它,有些服务器可能会直接拒绝连接。

504 – Gateway Timeout(网关超时)

504(Gateway Timeout)响应状态码表示服务器在作为网关或代理时,没有收到它需要访问的上游服务器的及时响应以完成请求。

该响应状态码与 502(Bad Gateway)类似,相关的应用场景也是类似的。

505 – HTTP Version Not Supported(HTTP 版本不支持)

505(HTTP Version Not Supported)响应状态码表示服务器不支持或拒绝支持请求消息中使用的 HTTP 主要版本。

HTTP 主要版本是形如 HTTP/x.y 表示的字符串,其中 x(主版本号)指明了 HTTP 的通信协议,y(子版本号)指明了发送者用于接下来收发消息的顺应且理解的版本。

RFC 7230§2.6

服务器表示不能或不愿意使用与客户端相同的主要版本来完成请求时,应该为 505 响应生成一个表示,说明为什么不支持该版本,以及该服务器支持哪些其他协议版本。

致谢

感谢 Taotie Languages。