前言

每一个 HTTP 请求的响应都会带有一个 HTTP 状态码(status code), 表示 HTTP 服务器响应状态的代码. 在 web 开发时, 经常遇到 200、301、404、500等. 如果我们清楚这些常见的状态码的含义, 发生的场景, 那么, 当线上出现问题的时候, 排查问题就游刃有余了.

HTTP 状态码分类

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用.

HTTP状态码共分为5种类型:

  • 1** 信息. 服务器收到请求,需要请求者继续执行操作
  • 2** 成功. 操作被成功接收并处理
  • 3** 重定向. 需要进一步的操作以完成请求
  • 4** 客户端错误. 请求包含语法错误或无法完成请求
  • 5** 服务器错误. 服务器在处理请求的过程中发生了错误

常见的状态码

1** 2** 3** 都不算异常状态码, 4** 代表客户端出错, 5** 代表服务端出错, 所以我们一般更加关注 4** 5** 类的状态码.

100 Continue

含义:继续发送

解释: 客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝. 客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应.服务器必须在请求完成后向客户端发送一个最终响应.

使用场景:

  1. http 100-continue用于客户端在发送POST数据给服务器前,征询服务器情况,看服务器是否处理POST的数据,如果不处理,客户端则不上传POST数据,如果处理,则POST上传数据. 在现实应用中,通常在POST大数据时,才会使用100-continue协议.
  2. 客户端策略
  • 如果客户端有POST数据要上传,可以考虑使用100-continue协议.加入头{“Expect”:”100-continue”}
  • 如果没有POST数据,不能使用100-continue协议,因为这会让服务端造成误解.
  • 并不是所有的Server都会正确实现100-continue协议,如果Client发送Expect:100-continue消息后,在timeout时间内无响应,Client需要立马上传POST数据.
  • 有些Server会错误实现100-continue协议,在不需要此协议时返回100,此时客户端应该忽略.
  1. 服务端策略
  • 正确情况下,收到请求后,返回100或错误码.
  • 如果在发送100-continue前收到了POST数据(客户端提前发送POST数据),则不发送100响应码(略去).

101 Switching Protocols

含义:协议升级

解释: 服务器已经理解了客户端的请求,并将通过 Upgrade 消息头通知客户端采用不同的协议来完成这个请求.在发送完这个响应最后的空行后,服务器将会切换到在 Upgrade 消息头中定义的那些协议.

使用场景: 只有在切换新的协议更有好处的时候才应该采取类似措施.例如,切换到新的 HTTP 版本比旧版本更有优势,或者切换到一个实时且同步的协议以传送利用此类特性的资源. 其实在浏览器上最常见的使用场景,就是 websocket 在进行跟服务器握手的时候,这时候服务端就会返回 201,从而进行协议升级,将协议从 http(s) 升级到 ws(s)

102 Processing

含义:进行中

解释: 代表处理将被继续执行.

使用场景: 这个其实是临时响应,主要是用来通知客户端,我已经接受到你的请求了,正在处理,但是可能得要一段时间,比如得 20s 之类的,但是放心,等我处理完之后,我会再发一个回执通知你.

200 OK

含义:请求成功

解释: 请求已成功,请求所希望的响应头或数据体将随此响应返回.

使用场景: 响应结果请求成功,表示客户端发来的请求在服务端被正常处理了.

201 Created

含义:服务器已经创建了文档,Location头给出了它的URL.

解释: 请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其URI已经随Location头信息返回.假如需要的资源无法及时建立的话,应当返回’202 Accepted’.

使用场景: PUT 一般用来创建资源,所以可以作为PUT请求的返回值.

202 Accepted

含义:已经接受请求,但处理尚未完成.

解释: 服务器已接受请求,但尚未处理.正如它可能被拒绝一样,最终该请求可能会也可能不会被执行. 在异步操作的场合下,没有比发送这个状态码更方便的做法了.返回202状态码的响应的目的是允许服务器接受其他过程的请求(例如某个每天只执行一次的基于批处理的操作),而不必让客户端一直保持与服务器的连接直到批处理操作全部完成.在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成.

使用场景: 这个状态码被设计用来将请求交由另外一个进程或者服务器来进行处理,或者是对请求进行批处理的情形.

206 Partial Content

含义:客户发送了一个带有Range头的GET请求,服务器完成了它(HTTP 1.1新)

解释: 表示客户端进行了范围请求,而服务器成功执行了这部分GET请求.响应报文中包含由Content-Range指定范围的实体内容. 服务器已经成功处理了部分 GET 请求.类似于FlashGet或者迅雷这类的HTTP下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载.该请求必须包含Range头信息来指示客户端希望得到的内容范围,并且可能包含If-Range来作为请求条件.

使用场景: 一般用来做断点续传,或者是视频文件等大文件的加载. 举个例子:加载一个mp4视频的请求,就是通过206响应来传输的, 而且这部分的处理全部是浏览器处理的

301 Moved Permanently(永久重定向)

含义:客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL.

解释: 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一.如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址.除非额外指定,否则这个响应也是可缓存的.新的永久性的URI 应当在响应的 Location 域中返回.除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明.如果这不是一个 GET 或者 HEAD 请求,因此浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化.注意:对于某些使用 HTTP/1.0 协议的浏览器,当它们发送的 POST 请求得到了一个301响应的话,接下来的重定向请求将会变成 GET 方式.

使用场景: 域名到期不想续费(或者发现了更适合网站的域名), 想换个域名. 在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个. 空间服务器不稳定,换空间的时候.

304 Not Modified(未修改)

含义:

客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档).服务器告诉客户,原来缓冲的文档还可以继续使用.

解释: 如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码.304响应禁止包含消息体,因此始终以消息头后的第一个空行结尾.

使用场景: 304虽然在3xx类别中,但是和重定向没关系, 主要用于浏览器缓存机制

308 Permanent Redirect(永久重定向)

含义:同301相同,不过重定向过程中,请求方法和消息主体不会发生改变

解释: 是表示重定向的响应状态码,说明请求的资源已经被永久的移动到了由 Location 首部指定的 URL 上.浏览器会进行重定向,同时搜索引擎也会更新其链接(用 SEO 的行话来说,意思是链接被传递到了新的 URL).在重定向过程中,请求方法和消息主体不会发生改变(返回 301 状态码的情况下,请求方法有时候会被客户端错误地修改为 GET 方法).

使用场景: 同301. 不过一些 Web 应用可能会将 308 Permanent Redirect 以一种非标准的方式使用以及用作其他用途.例如,Google Drive 会使用 308 Resume Incomplete 状态码来告知客户端文件上传终止且不完整.

400 Bad Request(坏请求)

含义:请求出现语法错误.

解释: 该状态码表示请求报文中存在语法错误.当错误发生时,需要修改请求的内容后再次发送请求.另外,浏览器会像200 OK一样对待该状态码.

使用场景: 语义有误,当前请求无法被服务器理解.除非进行修改,否则客户端不应该重复提交这个请求. 请求参数有误.

401 Unauthorized(未授权)

含义:

客户端试图未经授权访问受密码保护的页面.应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的Authorization头后再次发出请求.

解释: 当前请求需要用户验证.该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息.客户端可以重复提交一个包含恰当的 Authorization 头信息的请求.如果当前请求已经包含了 Authorization 证书,那么401响应代表着服务器验证已经拒绝了那些证书.如果401响应包含了与前一个响应相同的身份验证询问,且浏览器已经至少尝试了一次验证,那么浏览器应当向用户展示响应中包含的实体信息,因为这个实体信息中可能包含了相关诊断信息.参见RFC 2617. 当浏览器初次接收到401响应,会弹出认证用的对话窗口.

使用场景: 客户端错误,指的是由于缺乏目标资源要求的身份验证凭证,发送的请求未得到满足.

403 Forbidden (禁止)

含义:资源不可用.服务器理解客户的请求,但拒绝处理它.通常由于服务器上文件或目录的权限设置导致.

解释: 服务器已经理解请求,但是拒绝执行它.与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交.如果这不是一个 HEAD 请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因.当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息.

使用场景: 未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)等列举情况都可能是发生403的原因. 经常出现的一种情况就是,nginx如果配置有问题的话,比如静态资源目录配错,或者权限不够,都会返回 403. 还有一种经常出现的情况就是,如果在外网环境下,然后访问只有内网IP才能访问都站点和资源,那么一般该内网站点,在校验ip都时候,如果发现不在白名单之内,那么就会返回一个403,表现禁止访问.

404 Not Found(未找到)

含义:无法找到指定位置的资源.

解释: 请求失败,请求所希望得到的资源未被在服务器上发现.没有信息能够告诉用户这个状况到底是暂时的还是永久的.假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址. 404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下.

使用场景: 服务器找不到资源时,或者服务器拒绝请求又不想说明理由时. 出现这个错误的最有可能的原因是服务器端没有这个页面.

405 Method Not Allowed(不允许使用的方法)

含义:请求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)对指定的资源不适用.

解释: 请求行中指定的请求方法不能被用于请求相应的资源.该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表.

使用场景: PUT,DELETE 方法会对服务器上的资源进行写操作,因而绝大部分的网页服务器都不支持或者在默认配置下不允许上述请求方法,对于此类请求均会返回405错误. 客户端请求使用的方法和服务端指定的方法不匹配

414 URI Too Long(请求URI太长)

含义:URI太长

解释: 请求的URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务.

使用场景: 本应使用POST方法的表单提交变成了GET方法,导致查询字符串(Query String)过长. 重定向URI “黑洞”,例如每次重定向把旧的 URI 作为新的 URI 的一部分,导致在若干次重定向后 URI 超长. 客户端正在尝试利用某些服务器中存在的安全漏洞攻击服务器.这类服务器使用固定长度的缓冲读取或操作请求的 URI,当 GET 后的参数超过某个数值后,可能会产生缓冲区溢出,导致任意代码被执行.没有此类漏洞的服务器,应当返回414状态码.

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

含义:服务器由于不支持其有效载荷的格式,从而拒绝接受客户端的请求.

解释: 对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝.

使用场景: 格式问题的出现有可能源于客户端在 Content-Type 或 Content-Encoding 首部中指定的格式,也可能源于直接对负载数据进行检测的结果. 比如上传接口,只允许接受视频,结果上传来一张图片上去,格式不符合,就可以返回这个.

421 There are too many connections from your internet address

含义: 连接数过多

使用场景: 从当前客户端所在的IP地址到服务器的连接数超过了服务器许可的最大范围.通常,这里的IP地址指的是从服务器上看到的客户端地址(比如用户的网关或者代理服务器地址).在这种情况下,连接数的计算可能涉及到不止一个终端用户.

429 Too Many Requests

含义: 请求太多

使用场景: 表示在一定的时间内用户发送了太多的请求,即超出了“频次限制”.

500 Internal Server Error(内部资源出错)

含义:服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理.

解释: 这个错误代码是一个通用的“全方位”响应代码.通常服务器管理员对于类似于 500 这样的错误会更加详细地记录相关的请求信息来防止以后同样错误的出现. 比较通用的来说,基本上500错误,就是服务端程序代码的逻辑错误,所以如果在测试环境开debug模式的话,这时候就会在控制台输出error log.

使用场景: 一般来说,这个问题都会在服务器端的源代码出现错误时出现.

501 Not Implemented

含义:服务器不支持实现请求所需要的功能.例如,客户端发出了一个服务器不支持的PUT请求.

解释: 服务器不支持当前请求所需要的某个功能, 需要被访问的 web 服务器去修复该问题.

使用场景: 当服务器无法识别请求的方法,并且无法支持其对任何资源的请求.

502 Bad Gateway(网关错误)

含义:服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答.

解释: 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应. 502 错误通常不是客户端能够修复的,而是需要由途径的Web服务器或者代理服务器对其进行修复.

使用场景: web 服务重启的时候. 举个例子:启动nginx,不启动php-fpm, 这时候 nginx服务器就会返回 502. 原因:nginx无法连接php-fpm,在达到nginx最大的超时时间的时候,nginx还没有获取到响应就会返回502

503 Service Unavailable(服务不可用)

含义:服务器由于维护或者负载过重未能应答.服务器返回503时可以提供一个 Retry-After头.

解释: 由于临时的服务器维护或者过载,服务器当前无法处理请求.这个状况是临时的,并且将在一段时间以后恢复.如果能够预计延迟时间,那么响应中可以包含一个 Retry-After 头用以标明这个延迟时间.如果没有给出这个 Retry-After 信息,那么客户端应当以处理500响应的方式处理它.

注意: 503状态码的存在并不意味着服务器在过载的时候必须使用它.某些服务器只不过是希望拒绝客户端的连接.

使用场景: 例如,Servlet可能在数据库连接池已满的情况下返回 503. 在服务器503错误出现了之后,大家不必担心的, 服务器或许就是正在维护或者暂停了,你可以联系一下服务器空间商.还有的时候cpu占用的频率大导致的.

504 Gateway Timeout(网关超时)

含义:作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答.

解释: 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应.

注意: 某些代理服务器在DNS查询超时时会返回400或者500错误

使用场景: 与状态码408类似, 但是响应来自网关或代理,此网关或代理在等待另一台服务器的响应时出现了超时. 一般是nginx做为反向代理服务器的时候,所连接的应用服务器譬如tomcat无响应导致的 . 504 和 502 的差别就是一个是超时,一个没有启动.

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

含义:服务器不支持请求中所指明的HTTP版本.

解释: 服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本.这暗示着服务器不能或不愿使用与客户端相同的版本.响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体.

使用场景: 有些服务器不支持HTTP早期的HTTP协议版本,也不支持太高的协议版本

511 Network Authentication Required

含义:表示客户端需要通过验证才能使用该网络.

解释: 该状态码不是由源头服务器生成的,而是由控制网络访问的拦截代理服务器生成的.

使用场景: 网络运营商们有时候会在准许使用网络之前要求用户进行身份验证、接受某些条款,或者进行其他形式的与用户之间的互动(例如在网络咖啡厅或者机场).他们通常用用户设备的 MAC 地址来进行识别.