HTTP/HTTPS 返回码大全
打开网页看到 404、写接口调试遇到 500、部署完站点显示 502——这些三位数就是 HTTP 状态码(返回码)。本页先讲怎么看懂它们,再给出一份完整对照表。
先说清楚:HTTPS 没有自己的一套返回码
很多人以为 HTTP 和 HTTPS 各有一套状态码,其实没有。
HTTPS = HTTP + TLS 加密。TLS 只负责把内容加密后传输,上层的请求和响应格式完全没变。所以 https:// 和 http:// 用的是同一套状态码,200 还是 200,404 还是 404。
真正的区别在于:HTTPS 多了一个"握手"阶段。如果证书过期、域名对不上、加密协议谈不拢,连接在握手阶段就断了,根本走不到 HTTP 这一层,也就没有任何状态码。浏览器这时显示的是 ERR_CERT_DATE_INVALID 这类错误,那不是状态码。这部分单独放在下面一节。
状态码是什么
你在浏览器输入网址,浏览器向服务器发一个请求,服务器回一个响应。响应的第一行就长这样:
HTTP/1.1 404 Not Found404是状态码,给程序看的,机器按它决定下一步怎么做Not Found是原因短语,给人看的,服务器可以自定义甚至留空,不要用它做判断
状态码只表示"这次 HTTP 请求本身的处理结果",不表示"你想办的事成没成"。这个区别在常见误区里还会展开。
在哪能看到状态码
浏览器:按 F12 打开开发者工具 → 切到"网络 / Network"标签 → 刷新页面 → 列表里每一行请求都有一列 Status。点进某一行还能看完整的请求头和响应头。这是排查网页问题最常用的入口。
命令行:用 curl(Windows 10/11 和 Git Bash 都自带)。
curl -I https://example.com # 只看响应头(含状态行)
curl -s -o /dev/null -w "%{http_code}\n" https://example.com # 只打印状态码第二条的意思是:安静模式(-s)、把网页内容丢掉(-o /dev/null)、只输出状态码(-w)。调试时很好用。
五大类:看头一位数就够了
状态码永远是三位数,第一位决定大类。先看第一位判断"该找谁",再看具体数字判断"具体哪出错"。
| 类别 | 含义 | 通常该找谁 |
|---|---|---|
| 1xx 信息 | 请求收到了,还在处理 | 一般不用管,浏览器自己处理 |
| 2xx 成功 | 请求成功处理了 | 正常 |
| 3xx 重定向 | 资源换地方了,需要再请求一次 | 一般不用管,浏览器自动跟随 |
| 4xx 客户端错误 | 请求方有问题:地址写错、没登录、没权限、参数不对 | 先查自己的请求 |
| 5xx 服务端错误 | 服务器有问题:代码崩了、超时、网关连不上后端 | 查服务器日志,或联系服务方 |
新手最该记住的分界线是 4xx 和 5xx:4xx 是"你的请求不对",5xx 是"服务器自己出毛病了"。搞反方向会浪费大量排查时间。
1xx 信息响应
这类响应是"中间状态",后面还会跟真正的响应,日常几乎见不到。
| 码 | 名称 | 说明 |
|---|---|---|
| 100 | Continue | 客户端先问"这么大的请求体你收不收",服务器答"继续发" |
| 101 | Switching Protocols | 同意切换协议,最常见于升级到 WebSocket |
| 102 | Processing | WebDAV 用,表示还在处理,别超时。已不推荐使用 |
| 103 | Early Hints | 正式响应之前先告诉浏览器"这些 CSS/JS 可以先预加载",用于提速 |
| 104 | Upload Resumption Supported | 断点续传相关,仍是临时登记的草案状态,尚未成为正式标准 |
2xx 成功
| 码 | 名称 | 说明 |
|---|---|---|
| 200 | OK | 最常见的成功。请求成功,响应体里有内容 |
| 201 | Created | 创建成功。POST 新建资源后返回,通常带 Location 头指向新资源 |
| 202 | Accepted | 已接收,但还没处理完(异步任务)。成不成还不知道 |
| 203 | Non-Authoritative Information | 成功,但内容被中间代理改过 |
| 204 | No Content | 成功,但没有响应体。删除操作、表单提交后不跳转常用 |
| 205 | Reset Content | 成功,并要求客户端重置表单 |
| 206 | Partial Content | 返回了部分内容。断点续传、视频拖进度条就靠它 |
| 207 | Multi-Status | WebDAV 用,一个响应里装多个子操作的结果 |
| 208 | Already Reported | WebDAV 用,避免重复列举同一资源 |
| 226 | IM Used | 返回的是差量更新结果,极少见 |
3xx 重定向
3xx 里真正要分清的是**"跳转后请求方法变不变"**——这是后端开发的高频坑。
| 码 | 名称 | 说明 |
|---|---|---|
| 300 | Multiple Choices | 有多个可选资源,让客户端挑。极少用 |
| 301 | Moved Permanently | 永久搬家。浏览器和搜索引擎会记住并更新书签。历史实现会把 POST 改写成 GET |
| 302 | Found | 临时搬家。同样存在把 POST 改写成 GET 的历史行为 |
| 303 | See Other | 明确要求用 GET 请求新地址。表单 POST 提交后跳转到结果页的标准做法 |
| 304 | Not Modified | 内容没变,用你本地缓存的版本。没有响应体,配合 If-None-Match / If-Modified-Since 使用 |
| 305 | Use Proxy | 已废弃,存在安全问题,不要用 |
| 306 | (未使用) | 保留编号,注册表中标记为 Unused |
| 307 | Temporary Redirect | 临时跳转,明确保持原方法和请求体。POST 跳转后还是 POST |
| 308 | Permanent Redirect | 永久跳转,明确保持原方法和请求体 |
怎么选:想"永久 + 不改方法"用 308,"临时 + 不改方法"用 307,"POST 完跳到结果页"用 303。301/302 因为历史实现不一致,在需要保持方法时不可靠。
http://自动跳到https://通常就是 301。用下面这条命令可以看到完整跳转链(每一跳的状态码和目标):bashcurl -sIL https://iana.org/ | grep -iE "^HTTP/|^location:"实际输出是
301→Location: https://www.iana.org/→200,也就是跳了一次后成功。
4xx 客户端错误:请求方有问题
这是你最常需要自己解决的一类。
| 码 | 名称 | 说明与常见原因 |
|---|---|---|
| 400 | Bad Request | 请求格式不对,服务器看不懂。常见于 JSON 写错、参数类型不对 |
| 401 | Unauthorized | 名字容易误导,实际是未认证:没登录、Token 没带或已过期。响应必须带 WWW-Authenticate 头 |
| 402 | Payment Required | 保留给付费场景,部分 API 用它表示欠费或超额 |
| 403 | Forbidden | 已认证但没权限,或服务器拒绝说明原因。改权限、换账号,重新登录通常没用 |
| 404 | Not Found | 资源不存在。先检查 URL 拼写、大小写、路由配置 |
| 405 | Method Not Allowed | 地址对但方法不对,比如接口只收 POST 你发了 GET |
| 406 | Not Acceptable | 服务器无法返回你在 Accept 头里要求的格式 |
| 407 | Proxy Authentication Required | 需要先通过代理服务器认证 |
| 408 | Request Timeout | 客户端发得太慢,服务器等超时了 |
| 409 | Conflict | 状态冲突,比如注册时用户名已存在、并发修改撞车 |
| 410 | Gone | 资源被永久删除。比 404 更明确:"曾经有,现在没了" |
| 411 | Length Required | 缺 Content-Length 头 |
| 412 | Precondition Failed | 条件请求的前置条件不满足 |
| 413 | Content Too Large | 请求体太大,最常见于上传大文件。旧名 Payload Too Large |
| 414 | URI Too Long | URL 太长,通常是该用 POST 却硬塞进查询参数 |
| 415 | Unsupported Media Type | Content-Type 不被支持,比如接口要 application/json 你发了表单格式 |
| 416 | Range Not Satisfiable | 请求的字节范围超出文件大小 |
| 417 | Expectation Failed | Expect 头的要求无法满足 |
| 418 | (未使用) | 出自 1998 年愚人节 RFC 的"我是茶壶"梗,注册表保留编号防止被占用 |
| 421 | Misdirected Request | 请求发到了无法处理该域名的服务器上 |
| 422 | Unprocessable Content | 格式没错但内容不合法,比如邮箱格式不对。旧名 Unprocessable Entity |
| 423 | Locked | WebDAV:资源被锁定 |
| 424 | Failed Dependency | WebDAV:依赖的前一个操作失败了 |
| 425 | Too Early | 拒绝处理可能被重放的请求 |
| 426 | Upgrade Required | 要求客户端升级协议 |
| 428 | Precondition Required | 要求带条件请求头,防止并发覆盖 |
| 429 | Too Many Requests | 请求太频繁被限流。响应常带 Retry-After 告诉你等多久,照着等,别硬刷 |
| 431 | Request Header Fields Too Large | 请求头太大,常见于 Cookie 堆积过多 |
| 451 | Unavailable For Legal Reasons | 因法律原因不可用。编号致敬《华氏 451 度》 |
401 和 403 的区别是面试和排查里的经典问题:401 = "你是谁我不知道"(去登录),403 = "我知道你是谁,但不让你进"(去要权限)。
5xx 服务端错误:服务器有问题
看到 5xx,先确认不是自己的问题,再去查服务端日志。
| 码 | 名称 | 说明与常见原因 |
|---|---|---|
| 500 | Internal Server Error | 服务端代码抛异常了,是个"兜底"错误。必须看服务器日志才知道真实原因 |
| 501 | Not Implemented | 服务器不支持该请求方法 |
| 502 | Bad Gateway | 网关(Nginx 等)连到后端,但后端返回了无效响应。常见于后端进程根本没启动或已崩溃 |
| 503 | Service Unavailable | 服务暂时不可用:过载、维护中、或被限流。通常是临时的,可能带 Retry-After |
| 504 | Gateway Timeout | 网关等后端响应超时。后端太慢或卡死了 |
| 505 | HTTP Version Not Supported | 不支持请求使用的 HTTP 版本 |
| 506 | Variant Also Negotiates | 服务器内容协商配置有误 |
| 507 | Insufficient Storage | WebDAV:存储空间不足 |
| 508 | Loop Detected | WebDAV:检测到无限循环 |
| 510 | Not Extended | 已废弃(注册表标记为 OBSOLETED),不要用 |
| 511 | Network Authentication Required | 需要先通过网络认证才能上网,用于需要登录门户的网络环境 |
502 / 503 / 504 怎么分:都发生在"网关 + 后端"的架构里。502 是后端回了但回得不对,504 是后端没在规定时间内回,503 是服务主动说自己现在不可用。
非标准状态码
下面这些不在标准里,是具体厂商或软件自己定义的。查错时能直接定位到是哪一层出的问题。
Cloudflare(5xx 系列)
如果站点挂在 Cloudflare 后面,出现 52x 说明问题在 Cloudflare 到你的源站服务器之间。
| 码 | 含义 |
|---|---|
| 520 | 源站返回了 Cloudflare 无法解析的响应 |
| 521 | 源站拒绝连接,通常是服务没起或防火墙拦了 Cloudflare 的 IP |
| 522 | 连接源站超时 |
| 523 | 源站不可达,常见于 DNS 或回源地址配错 |
| 524 | 连上了源站,但源站处理太久没返回 |
| 525 | 与源站的 SSL 握手失败 |
| 526 | 源站的 SSL 证书无效 |
| 530 | 通常与一个 1xxx 错误码一起出现,看那个码才知道原因 |
Nginx(内部使用)
这些码定义在 Nginx 源码里,主要出现在访问日志中,Nginx 一般不会把它们发给浏览器。
| 码 | 含义 |
|---|---|
| 444 | 直接关闭连接,不返回任何响应。常用于屏蔽恶意请求 |
| 494 | 请求头过大 |
| 495 | 客户端证书错误 |
| 496 | 需要客户端证书但没提供 |
| 497 | 把普通 HTTP 请求发到了 HTTPS 端口上,比如访问 http://站点:443 |
| 499 | 客户端在服务器返回前主动断开了连接。日志里大量 499 通常意味着后端太慢,用户等不及关掉了页面 |
HTTPS 特有的报错(不是状态码)
回到开头那句话:TLS 握手失败发生在 HTTP 之前,没有状态码。浏览器显示的是这类错误名,认识它们能快速定位:
| 浏览器错误 | 含义 | 常见原因 |
|---|---|---|
ERR_CERT_DATE_INVALID | 证书日期无效 | 证书过期忘了续期;或者本机系统时间不对 |
ERR_CERT_AUTHORITY_INVALID | 签发机构不受信任 | 自签名证书;或中间证书没配全 |
ERR_CERT_COMMON_NAME_INVALID | 证书域名对不上 | 证书签给了 a.com,你访问的是 b.com |
ERR_SSL_PROTOCOL_ERROR | 协议层握手失败 | 双方支持的 TLS 版本或加密套件没有交集 |
SEC_ERROR_UNKNOWN_ISSUER | 同上,Firefox 的叫法 | 同上 |
排查顺序建议:
- 先看本机时间是否正确——时间不对会让所有正常证书都显示过期,这是最容易忽略的原因
- 换个网络或设备试试,判断是站点问题还是本机/网络问题
- 点开浏览器地址栏的锁图标查看证书详情,确认签发者、有效期、域名
- 自己的站点则检查证书链是否完整、有没有配置自动续期
遇到证书警告时不要习惯性点"继续访问"。在校园网、公共 Wi-Fi 等环境下,证书异常可能意味着流量被中间人截获,输入的账号密码会直接泄露。
快速排查对照
| 现象 | 先查什么 |
|---|---|
| 404 | URL 拼写、大小写、路由是否注册、文件是否真的部署上去了 |
| 401 | Token 是否携带、是否过期、请求头名字是否写对 |
| 403 | 账号权限、资源归属、服务端的 IP/来源限制 |
| 405 | 请求方法是否与接口定义一致 |
| 415 | Content-Type 是否与接口要求匹配 |
| 429 | 看 Retry-After,降低请求频率,加重试退避 |
| 500 | 看服务端日志,状态码本身不含信息量 |
| 502 / 504 | 后端进程是否存活、端口是否正确、是否超时 |
| 503 | 是否在维护、是否过载、稍后重试 |
| 完全没有状态码 | 说明请求没走到 HTTP 层:查 DNS、网络连通性、TLS 证书 |
常见误区
误区一:200 就等于业务成功。 很多 API 无论成功失败都返回 200,把真正的结果塞在响应体里,比如 {"code": 1001, "message": "余额不足"}。HTTP 状态码描述的是"这次通信"的结果,不是"这件事"的结果。 对接接口时一定要看文档,别只判断状态码。
误区二:看到错误页就以为是 4xx/5xx。 有些网站出错时照样返回 200,只是页面内容是一张错误图。反过来,返回 404 的页面也可能长得很正常。以开发者工具里的 Status 列为准。
误区三:把 401 当成"没权限"。 401 是没认证(去登录),403 才是没权限(去要授权)。搞混会导致一直在重新登录却始终进不去。
误区四:以为 CORS 报错是状态码问题。 跨域被拦截时,请求其实可能已经成功返回了 200,是浏览器出于安全策略不让 JavaScript 读取结果。控制台里的 blocked by CORS policy 需要在服务端配置响应头解决,改前端请求方式没用。
误区五:遇到 429 就狂点刷新。 这只会让限流窗口一直重置,越刷越进不去。按 Retry-After 等待才是正确做法。
参考来源
- IANA HTTP Status Code Registry:状态码的权威登记表,判断某个码是否正式存在以此为准
- RFC 9110: HTTP Semantics:现行 HTTP 语义标准,第 15 节是状态码定义
- MDN:HTTP 响应状态码:中文说明详细,适合日常查阅
- Cloudflare 5xx 错误排查文档
更多技术主题见技术资源导航。