常见 HTTP 状态详解及示例

HTTP 协议,是每位 Web 开发工程师需要了解的基本协议之一;HTTP 协议提供的各种状态码,更是前后端程序员需要掌握的知识。本文将详细介绍 HTTP 各种常见的状态码,从 1xx5xx,并配合详细的示例来说明每种状态的使用场景。

1xx 状态码

101 Switch Protocols

表示升级协议(如从 http://ws://),此时需要反向代理支持,如 Nginx,在 Nginx 配置 WebSocket 如下:

location / {
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection  $connection_upgrade;
}

 下图展示了 101 Switch Protocols 响应状态:

101 Switch Protocols 响应状态
101 Switch Protocols 响应状态

2xx 状态码

200 OK

表示资源请求成功,这是我们最常见的状态码。

例如,请求本站首页,响应头部如下所示:

curl -I https://www.dute.org
HTTP/2 200
server: nginx
...

201 Created

表示资源创建成功,多用于 POST 请求。

204 No Content

该响应不会返回 Body,一般有以下两种情况:

  • 与 Options/Delete 请求搭配
  • 打点类

示例一:掘金为 Options 请求的状态码设置为 204

掘金 204 响应状态码
掘金 204 响应状态码

示例二:知乎为 Delete 请求的状态码设置为 204,以下请求为取消关注时的响应状态:

知乎取消关注返回 204 状态
知乎取消关注返回 204 状态

示例三:浏览知乎网页时,打开控制台,会发现一个是 204 的状态码:

curl 'https://www.zhihu.com/sc-profiler' \
     -H 'content-type: application/json' \
     --data-binary '[["i","production.heifetz.main.desktop.v1.Collector.screen.1536_960.count",1,1]]' \
     --compressed -vvv
...
< HTTP/2 204
< server: CLOUD ELB 1.0.0
< date: Thu, 14 Jan 2021 11:03:51 GMT
< content-type: text/html
< vary: Accept-Encoding
< x-backend-response: 0.001
< cache-control: no-cache, no-store, must-revalidate, private, max-age=0
< pragma: no-cache
< referrer-policy: no-referrer-when-downgrade

206 Partial Content

当数据较大时(如:请求多媒体数据),会进行分片传输。当你在 B 站观看视频,打开开发者工具,会发现许多 206 状态码以及响应头 Content-Range

B 站 206 响应状态
206 响应状态

注:本站提供了 Bilibili 视频封面获取工具,有兴趣的可以点击查看使用。

3xx 状态码

301 Moved Permanently

表示永久重定向。当 http 转向 https 协议时,有时会使用 301 状态码;此时浏览器会自动缓存,下次直接自动跳转,不再请求服务器。

下面是以 http 协议请求本站首页时的响应状态:

curl -I http://www.dute.org
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 14 Jan 2021 11:08:51 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://www.dute.org/

通常,301 状态的响应头部,会包含 Location 字段,表示重定向的地址。

302 Found

表示已找到资源,进行临时重定向。有时,http 跳转到 https 时,也会使用 302 状态码,如知乎的跳转:

curl -I http://www.zhihu.com
HTTP/1.1 302 Found
Location: https://www.zhihu.com/
Content-Length: 0
X-NWS-LOG-UUID: 7170541457873901785
Connection: keep-alive
Server: Lego Server
Date: Thu, 14 Jan 2021 11:22:50 GMT
X-Cache-Lookup: Return Directly

304 Not Modified

表示资源自上次请求后,未发生变化,即资源已被缓存。通常,伴随 304 状态一起返回的还有 ETagLast-ModifiedIf-Modified-SinceExpires 等响应头部。

该响应状态一般用于静态资源(如静态 index.html、图片、JS/CSS 文件),以提升页面加载速度。

307 Temporary Redirect

表示暂时重定向(或内部重定向)。该状态也可作为 httphttps 的重定向的状态。307 状态码还可以用作 HSTS,当谷歌浏览器发现某 http 资源已被加入到 HSTS 列表,浏览器内部会通过 307 作重定向。

Stackoverflow 307 响应状态码
Stackoverflow 307 响应状态码

301,302 和 307 状态有什么区别?

  • 301 Moved Permanently:表示永久重定向,该操作比较危险,需要谨慎操作:如果设置了 301,但是一段时间后又想取消,此时浏览器中已经有了缓存,还是会重定向
  • 302 Found:表示临时重定向,但是会在重定向的时候改变 method,即把 POST 改成 GET,为了避免这种情况发生,便有了 307 状态
  • 307 Temporary Redirect:表示临时重定向,在重定向时不会改变 method

308 Permanent Redirect

表示永久重定向。308 状态与 301 状态不同的是,当它重定向到新的地址时,并不会改变 method。

4xx 状态码

400 Bad Request

该状态表示,对于服务器无法理解的参数,将会使用 400 作为响应状态码。一种典型情况是,当使用 Content-Type: JSON 时,服务器解析 JSON 失败了,此时会返回 400 状态。

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}

401 Unauthorized

当没有权限的用户请求需要带有权限的资源时,会返回 401 状态(另外,有时候认证失败也会返回该状态)。

解决方案:在请求资源时,带上正确的凭证可以解决该问题。

示例:Github 中用错误的凭证信息请求受保护资源

curl -i https://api.github.com -u foo:bar
HTTP/1.1 401 Unauthorized

{
  "message": "Bad credentials",
  "documentation_url": "https://developer.github.com/v3"
}

403 Forbidden

该状态表示资源禁止访问 — 不管提供的权限凭证是否正确!

401 和 403 状态码的区别:

当用于用户未提供授权凭证或提供的授权凭证错误时,使用 401 响应码;而 403 状态码直接禁止访问指定的资源(无论是否通过用户认证)。

404 Not Found

这是一个很常见的响应状态,表示请求的资源(页面)不存在。

下面是请求本站一个不存在的页面时的响应头部信息:

curl -I https://www.dute.org/not-found
HTTP/2 404
server: nginx
date: Fri, 15 Jan 2021 01:24:12 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
set-cookie: _dtool=2raujgm0p2qehsdesg8sr5f54oi3de4i; expires=Mon, 18-Jan-2021 01:24:12 GMT; Max-Age=259200; path=/; HttpOnly
expires: Thu, 19 Nov 1981 08:52:00 GMT
cache-control: no-store, no-cache, must-revalidate
pragma: no-cache

405 Method Not Allowed

表示不支持使用的 HTTP 请求方法。例如,页面要求接收 POST 请求,但是发送的是 GET 请求。关于 HTTP 请求方法的说明,请参考《HTTP 请求方法一览》。

411 Length Required

表示在请求头部中,需要包含 Content-Length 字段,否则,服务器无法处理。

413 Payload Too Large

表示请求实体(body)过大,服务器无法处理。

414 URI Too Long

表示请求的 URL 太长,导致服务器无法处理。

422 Unprocessable Entity

表示虽然请求格式正确,但由于语义上的错误,导致服务器无法响应请求。该状态常用来处理不合法的参数校验。

例如,在 Github 上给某个项目点赞时,当设置一个不正确的参数命名时,会返回 422 状态码:

GitHub 422 响应状态
GitHub 422 响应状态

423 Locked

表示正在访问的资源已被锁定。

429 Too Many Request

表示请求过多或太频繁被服务器限流。

一些 API 服务,当超过其设定的 Rate Limit 规则时,会被限流,此时,服务器应返回 429 状态码来表示此种情况。

5xx 状态码

500 Internal Server Error

表示服务器内部错误。服务器报这种错误,一种常见的原因是应用层未捕获错误而导致整个服务不可用。

502 Bad Gateway

当服务器作为网关或代理,从上游服务器收到无效响应时,会返回 502 状态。这种状态在运行 Nginx 的服务器上比较常见,上游应用层未返回响应或者上游程序挂了,均会导致这种情况。

503 Service Unavailable

表示(由于超载或停机维护)服务不可用,这通常是一种暂时状态,系统维护好之后便会恢复。

504 Gateway Timeout

表示网关超时。也即是说,服务器作为网关或代理,没有及时从上游服务器收到请求,这时,就会返回 504 状态码。

总结

本文详细介绍了常用 HTTP 状态码的含义,同时,辅以相关的示例进行说明,如需了解更多的 HTTP 状态,请参考本站的《HTTP 状态码参考表》,该表提供了更全面的 HTTP 状态说明。

附:相关工具推荐

分享