HTTP 协议,是每位 Web 开发工程师需要了解的基本协议之一;HTTP 协议提供的各种状态码,更是前后端程序员需要掌握的知识。本文将详细介绍 HTTP 各种常见的状态码,从 1xx
到 5xx
,并配合详细的示例来说明每种状态的使用场景。
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 响应状态:
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
。
示例二:知乎为 Delete
请求的状态码设置为 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
。
注:本站提供了 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
状态一起返回的还有 ETag
、Last-Modified
、If-Modified-Since
、Expires
等响应头部。
该响应状态一般用于静态资源(如静态 index.html、图片、JS/CSS 文件),以提升页面加载速度。
307 Temporary Redirect
表示暂时重定向(或内部重定向)。该状态也可作为 http
到 https
的重定向的状态。307
状态码还可以用作 HSTS,当谷歌浏览器发现某 http 资源已被加入到 HSTS 列表,浏览器内部会通过 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
状态码:
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 状态说明。
附:相关工具推荐