HTTP 状态码

1. 作用及分类

1.1 作用

状态码是当客户端向服务器发出请求时,用来描述请求返回的结果的。
借助状态码,客户端可以知道请求是被正确处理了,还是在哪个部分出现了问题。

1.2 分类

状态码由 3 个数字和一个状态短语组成,例如 200 OK
其中数字的第一位表示状态码的类别,根据请求结果的不同,可以将状态码分为 5 个类别:

类别 状态短语
1xx 信息性 接收的请求正在处理
2xx 成功 请求正常处理完毕
3xx 重定向 需要进行附加操作来完成请求
4xx 客户端错误 服务器无法处理请求
5xx 服务器错误 服务器处理请求出现错误

2. 2xx 成功

2xx 表示响应结果得到成功的处理

  • 200 OK
    表示从客户端发来的请求得到的服务器的正常处理

  • 204 No Content
    表示从客户端发来的请求在服务器端成功处理了,但是没有资源可返回,也就是没有实体部分。例如,当你使用 PUT 成功更新一个资源后,如果服务器完整接受了客户端的更新,没有拒绝也没有额外更新,那实际上是不需要返回任何东西的,因为现在客户端和服务器端已经拥有完全一致的状态。在这种情况下,服务器可以返回 204 No Content,同时 body 为空,客户端就知道它的状态已经跟服务器端同步了。

  • 206 Partial Content
    该状态码表示客户端进行了范围请求,而服务器正常处理了这个范围请求。响应报文中包含了由 Content-Range 字段指定范围的 实体 内容。

3. 3xx 重定向

3xx 表示需要浏览器做一些特殊的处理以正确处理请求

  • 301 Moved Permanently
    永久性重定向。该状态码表示请求的资源被分配了新的地址。如果已经把资源对应的地址保存为书签了,就应该将其更新。

  • 302 Found
    临时重定向。请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。
    GET/ HEAD => 重定向用回原本的方法 (GET => GET, HEAD => HEAD); POST/ DELETE => 要問客戶是否重定向

  • 303 See Other
    临时重定向。该状态码表示由于请求的资源被分配了新地址,应该使用 GET 方法定向获取请求的资源。
    POST => 重定向用 GET (不用问客戶否重定向)

  • 304 Not Modified
    该状态码表示客户端发送了带条件的请求(采用 GET 方法的请求报文中包含If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, If-Range中的任一个首部),服务器允许请求访问资源,但是当请求中的条件不能被满足时,就会返回 304 Not Modified(服务器资源未改变,可直接使用客户端未过期的缓存)。
    304 状态码返回时,不包含任何主体部分。

  • 307 Temporary Redirect
    临时重定向。请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。
    GET/ HEAD => 重定向用回原本的方法 (GET => GET, HEAD => HEAD); POST/ DELETE => 要問客戶是否重定向

302,303,307区别

302,303,307都是临时重定向,按说应该有不同的功能,可是为什么302和307是一模一样的,这就要从 HTTP 协议的历史说起。

这三个状态码,都是说,客户端请求的 url 临时失效了,在响应的报文中,写上了新的有效 url,但是之后的请求还是用老的 url。
那它们的区别是什么呢,区别在怎么根据返回的有效 url 处理这次的请求。

HTTP 1.0 版本中,在处理临时重定向时,只有302,303两个状态码。302 告诉客户端,如果你之前是用 POST 方法,那么还用 POST 方法访问新 url,但是重定向之前要先询问客户是否重定向。
而 303,则强制将 POST 换成 GET ,并删除请求报文中的主体,去访问新 url,而且不用询问。

可是,支持 HTTP 1.0 版本的浏览器厂商在实现时,把 302 等同于 303,也就是说,只要收到 302 或 303 中的一个,强制将 POST 换成 GET ,并删除请求报文中的主体,去访问新 url,并且是自动再次发送请求。

但是,到了 HTTP 1.1 时代,既要实现更加规范化,又要实现兼容性,如果强制将 302,303区分,会造成混乱,多以只能再增加了一个 307 状态码,表示原先 302 状态码的意思。这样。无论 1.0 版本,还是 1.1 版本,302,303 实际上都是一个意思。

4. 4xx 客户端错误

  • 400 Bad Request
    该状态码表示请求报文中有语法错误。当错误发生时,需要修改请求中的错误内容后再次发送请求。另外,浏览器会向对待 200 OK 一样对待该状态码。

  • 401 Unauthorized
    该状态码表示发送的请求需要有通过 HTTP 认证的(BASIC, DIGEST认证)的认证信息。浏览器初次接收到 401 时,会弹出认证用的对话框。
    如果之前已经进行过一次请求,再次收到 401 表示认证失败。

  • 403 Forbidden
    该状态码表示服务器拒绝客户端请求资源的访问,一般是客户端没有获得服务器的授权。

  • 404 Not Found
    该状态码表示服务器上无法找到请求的资源。除此之外,也可以在服务器拒绝请求且不想说明理由时使用。

5. 5xx 服务器错误

  • 500 Internal Server Error
    该状态码表示服务器在执行请求时发生了错误。也有可能是 Web 应用发生的 bug 或某些临时的故障。

  • 503 Server Unavailable
    该状态码表示服务器暂时处于超负载或正进行停机维护,现在无法处理请求。

本文参考:

  1. HTTP 状态码详解
  2. 图解 HTTP