# status line

表示服务器响应的状态，比如 `HTTP/1.1 200 OK`

![](https://605825044-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVUa7MztTVfoHQxXozBQf%2Fuploads%2FqmUu97Lf44lHfVMjYrf7%2Fimage.png?alt=media\&token=587c41a0-9c8f-4065-85b1-9b91f1eb62b5)

<table><thead><tr><th width="142">组成部分</th><th width="98">含义</th><th>说明</th></tr></thead><tbody><tr><td>version</td><td>版本号</td><td>报文使用的 HTTP 协议版本</td></tr><tr><td>status code</td><td>状态码</td><td>一个三位数，表示响应的处理结果<br>比如 200 是成功，500 是服务器错误</td></tr><tr><td>reason</td><td>原因短语</td><td>是对 status code 的简短文字描述<br>但其早期只是为了兼容不同的文本客户端，而且提供的信息很有限，目前大多数客户端都会忽略它</td></tr></tbody></table>

```bash
# client 你好，我已经处理完了你的请求，这是处理结果
#   这个报文使用的协议版本号是 1.1，
#   处理结果的状态码是 200，一切 OK
HTTP/1.1 200 OK

# client 抱歉啊，你的请求我收到了，但我没找到你要的资源
HTTP/1.1 404 Not Found
```

## status code

status code（状态码）表示服务器对请求的处理结果，客户端可以依据它适时转换处理状态，比如继续发送请求、切换协议，重定向跳转等，有那么点 TCP 状态转换的意思。

目前 RFC 标准里规定的状态码是三位数，所以取值范围就是从 000 到 999。考虑到灵活性和可扩展性，状态码用数字的第一位表示分类：

<table><thead><tr><th width="104.33333333333331">分类</th><th width="115">含义</th><th>说明</th></tr></thead><tbody><tr><td>1××</td><td>提示信息</td><td>表示目前是协议处理的中间状态<br>实际用到的很少</td></tr><tr><td>2××</td><td>成功</td><td>报文已经收到并被正确处理</td></tr><tr><td>3××</td><td>重定向</td><td>表示客户端请求的资源发生了变动<br>客户端必须使用新的 URI 重新发送请求获取资源</td></tr><tr><td>4××</td><td>客户端错误</td><td>请求报文有误，服务器无法处理</td></tr><tr><td>5××</td><td>服务器错误</td><td>服务器在处理请求时内部发生了错误</td></tr></tbody></table>

在 HTTP 协议中，正确地理解并应用这些状态码不是客户端或服务器单方的责任，而是双方共同的责任。

目前 RFC 标准里总共有 41 个状态码，但状态码的定义是开放的，允许自行扩展。所以 Apache、Nginx 等 Web 服务器都定义了一些专有的状态码。

### 1×× 提示信息

<table><thead><tr><th width="104.33333333333331">状态码</th><th width="186">原因短语</th><th>说明</th></tr></thead><tbody><tr><td>100</td><td>Continue</td><td>继续。客户端应继续其请求</td></tr><tr><td><mark style="color:purple;">101</mark></td><td><mark style="color:purple;">Switching Protocols</mark></td><td>切换（到更高级的）协议。服务器根据客户端的请求切换协议，比如切换到 HTTP 的新版本协议，比如用 Upgrade 头字段切换到 WebSocket 协议</td></tr></tbody></table>

### 2×× 成功

<table><thead><tr><th width="112.33333333333331">状态码</th><th width="171">原因短语</th><th>说明</th></tr></thead><tbody><tr><td><mark style="color:purple;">200</mark></td><td><mark style="color:purple;">OK</mark></td><td>请求成功。一般用于 GET 与 POST 请求，会返回请求所要的响应头和数据，即全量数据。</td></tr><tr><td>201</td><td>Created</td><td>已创建。成功请求并创建了新的资源</td></tr><tr><td>202</td><td>Accepted</td><td>已接受。已经接受请求，但未处理完成</td></tr><tr><td>203</td><td>Non-Authoritative Information</td><td>非授权信息。请求成功，但返回的 meta 信息不在原始的服务器，而是一个副本</td></tr><tr><td><mark style="color:red;">204</mark></td><td><mark style="color:red;">No Content</mark></td><td>含义与 200 基本相同，只是没有 body 数据。比如在未更新网页的情况下，可确保浏览器继续显示当前文档</td></tr><tr><td>205</td><td>Reset Content</td><td>重置内容。服务器处理成功，用户终端（如浏览器）应重置文档视图，可通过此返回码清除浏览器的表单域</td></tr><tr><td><mark style="color:red;">206</mark></td><td><mark style="color:red;">Partial Content</mark></td><td>部分内容。在客户端发送“范围请求”、要求获取资源的部分数据时出现，是 HTTP 分块下载或断点续传的基础。它与 200 一样，也是服务器成功处理了请求，只是 body 里的数据不是资源的全部，通常伴随着头字段 Content-Range</td></tr></tbody></table>

### 3×× 重定向

<table><thead><tr><th width="104.33333333333331">状态码</th><th width="131">原因短语</th><th>说明</th></tr></thead><tbody><tr><td>300</td><td>Multiple Choices</td><td>多种选择。请求的资源可包括多个位置，相应可返回一个资源特征与地址的列表用于客户端选择</td></tr><tr><td><mark style="color:purple;">301</mark></td><td><mark style="color:purple;">Moved Permanently</mark></td><td>永久移动（永久重定向）。表示请求的资源已经不存在了，需要换成新 URI 再次访问，其中新 URI 通过响应头里的 Location 指定，值可能是多个。此时，浏览器会自动定向到新 URI，今后任何新的请求都应使用新的 URI 代替。如果可能，拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定，否则这个响应也是可缓存的（即 301 会触发缓存优化）</td></tr><tr><td><mark style="color:purple;">302</mark></td><td><mark style="color:purple;">Found</mark></td><td>临时移动（临时重定向）。意思是请求的资源还在，但需要暂时用另一个 URI 来访问。只有指定了 <code>Cache-Control</code> 或 <code>Expires</code> 的情况下，该响应才是可缓存的。</td></tr><tr><td>303</td><td>See Other</td><td>查看其它地址。与 301 类似，使用 GET 和 POST 请求查看</td></tr><tr><td><mark style="color:red;">304</mark></td><td><mark style="color:red;">Not Modified</mark></td><td>表示资源未修改，通常与 If-Modified-Since 等条件请求一起，用于缓存控制。它不具有通常意义上的跳转含义，但可以理解成重定向已到缓存的文件，缓存重定向</td></tr><tr><td>305</td><td>Use Proxy</td><td>使用代理。所请求的资源必须通过代理访问</td></tr><tr><td>306</td><td>Unused</td><td>已经被废弃的 HTTP 状态码</td></tr><tr><td>307</td><td>Temporary Redirect </td><td>临时重定向。与 302 类似，使用 GET 请求重定向</td></tr><tr><td>308</td><td></td><td></td></tr></tbody></table>

应用场景：

* 资源不可用：需要用另一个新的 URI 来代替，比如域名变更、服务器变更、网站改版、系统维护
* 避免重复：让多个网址都跳转到一个 URI，增加访问入口的同时还不会增加额外的工作量。比如有的网站都会申请多个名称类似的域名，然后把它们再重定向到主站上

永久 vs 临时：

* 永久：如果域名、服务器、网站架构发生了大幅度的改变，比如启用了新域名、服务器切换到了新机房、网站目录层次重构
* 临时：比如系统维护，把网站重定向到一个通知页面，告诉用户过一会儿再来访问。比如服务降级，在双十一时，把订单查询、领积分等不重要的功能入口暂时关闭，保证核心服务能够正常运行

### 4×× 客户端错误

4×× 类状态码表示客户端发送的请求报文有误，服务器无法处理。它是真正意义上的“错误码”。

<table><thead><tr><th width="100.33333333333331">状态码</th><th width="172">原因短语</th><th>说明</th></tr></thead><tbody><tr><td><mark style="color:purple;">400</mark></td><td><mark style="color:purple;">Bad Request</mark></td><td>客户端请求的语法错误，服务器无法理解。比如数据类型不匹配，比如应该是 JSON 字符串却传了对象，比如字段名称和字段类型不一致。<mark style="color:red;">（待确认？？）</mark><br>是一个通用的错误码。应当尽量避免给客户端返回 400，而是换作其它更有明确含义的状态码。</td></tr><tr><td>401</td><td>Unauthorized</td><td>请求要求用户的身份认证。当前请求需要用户验证</td></tr><tr><td>402</td><td>Payment Required</td><td>保留，为将来使用</td></tr><tr><td><mark style="color:purple;">403</mark></td><td><mark style="color:purple;">Forbidden</mark></td><td>实际上不是客户端的请求出错，而是服务器禁止访问资源。原因可能多种多样，比如信息敏感、法律禁止等，如果服务器友好一点，可以在 body 里详细说明拒绝请求的原因</td></tr><tr><td><mark style="color:purple;">404</mark></td><td><mark style="color:purple;">Not Found</mark></td><td>服务器无法根据客户端的请求找到资源(网页)。通过此代码，网站设计人员可设置“您所请求的资源无法找到”的个性页面</td></tr><tr><td><mark style="color:orange;">405</mark></td><td><mark style="color:orange;">Method Not Allowed</mark></td><td>不允许使用某些方法操作资源，比如不允许 POST 只能 GET；</td></tr><tr><td><mark style="color:orange;">406</mark></td><td><mark style="color:orange;">Not Acceptable</mark></td><td>资源无法满足客户端请求的条件，比如请求中文但只有英文</td></tr><tr><td>407</td><td>Proxy Authentication Required</td><td>请求要求代理的身份认证，与 401 类似，但请求者应当使用代理进行授权</td></tr><tr><td><mark style="color:orange;">408</mark></td><td><mark style="color:orange;">Request Time-out</mark></td><td>请求超时，服务器等待了过长的时间</td></tr><tr><td><mark style="color:orange;">409</mark></td><td><mark style="color:orange;">Conflict</mark></td><td>多个请求发生了冲突，可以理解为多线程并发时的竞态</td></tr><tr><td>410</td><td>Gone</td><td>客户端请求的资源已经不存在。410 不同于 404，如果资源以前有现在被永久删除了可使用 410 代码，网站设计人员可通过 301 代码指定资源的新位置</td></tr><tr><td>411</td><td>Length Required</td><td>服务器无法处理客户端发送的不带 Content-Length 的请求信息</td></tr><tr><td>412</td><td>Precondition Failed</td><td>客户端请求信息的先决条件错误</td></tr><tr><td><mark style="color:orange;">413</mark></td><td><mark style="color:orange;">Request Entity Too Large</mark></td><td>请求报文里的 body 太大，服务器无法处理。为防止客户端的连续请求，服务器可能会关闭连接。如果只是服务器暂时无法处理，则会包含一个 Retry-After 的响应信息</td></tr><tr><td><mark style="color:orange;">414</mark></td><td><mark style="color:orange;">Request-URI Too Large</mark></td><td>请求行里的 URI 过长，服务器无法处理</td></tr><tr><td>415</td><td>Unsupported Media Type</td><td>服务器无法处理请求附带的媒体格式</td></tr><tr><td>416</td><td>Requested range not satisfiable</td><td>客户端请求的范围无效</td></tr><tr><td>417</td><td>Expectation Failed</td><td>服务器无法满足 Expect 的请求头信息</td></tr><tr><td><mark style="color:orange;">429</mark></td><td><mark style="color:orange;">Too Many Requests</mark></td><td>客户端发送了太多的请求，通常是由于服务器的限连策略</td></tr><tr><td><mark style="color:orange;">431</mark></td><td><mark style="color:orange;">Request Header Fields Too Large</mark></td><td>请求头某个字段或总体太大</td></tr></tbody></table>

### 5×× 服务端错误

5×× 类状态码表示客户端请求报文正确，但服务器在处理时内部发生了错误，导致无法返回应有的响应数据。

<table><thead><tr><th width="96.33333333333331">状态码</th><th width="187">原因短语</th><th>说明</th></tr></thead><tbody><tr><td><mark style="color:purple;">500</mark></td><td><mark style="color:purple;">Internal Server Error</mark></td><td>与 400 类似，也是一个通用的错误码。服务器究竟发生了什么错误我们不知道。不过对于服务器来说，这应该算是好事，通常不应该把服务器内部的详细信息告诉外界。</td></tr><tr><td><mark style="color:purple;">501</mark></td><td><mark style="color:purple;">Not Implemented</mark></td><td>表示客户端请求的功能还不支持。类似“即将开业，敬请期待”</td></tr><tr><td><mark style="color:purple;">502</mark></td><td><mark style="color:purple;">Bad Gateway</mark></td><td>通常是服务器作为网关或者代理时返回的错误码，表示服务器自身工作正常，访问后端服务器时发生了错误，但具体的错误原因也是不知道的</td></tr><tr><td><mark style="color:purple;">503</mark></td><td><mark style="color:purple;">Service Unavailable</mark></td><td>表示服务器当前很忙，暂时无法响应服务，我们上网时有时候遇到的“网络服务正忙，请稍后重试”的提示信息就是 503。503 通常是个临时的状态，很可能过几秒钟后服务器就不那么忙了，可以继续提供服务，所以 503 响应报文里通常还会有一个 Retry-After 字段，指示客户端可以在多久以后再次尝试发送请求。</td></tr><tr><td>504</td><td>Gateway Time-out</td><td>充当网关或代理的服务器，未及时从远端服务器获取请求</td></tr><tr><td>505</td><td>HTTP Version not supported</td><td>服务器不支持请求的 HTTP 协议的版本，无法完成处理</td></tr></tbody></table>
