状态码是服务器的一句回话
每次你在浏览器里敲一个地址,服务器回给你的第一句话就是状态码。三个数字,说的是"这次请求我处理得怎么样"。
多数人只在出错时才注意到它。页面上跳出一句"500 Internal Server Error",或者接口调试工具里红着一行 404,然后就是找同事问、在群里发截图,来回半天。其实状态码已经把问题指向哪里说得很清楚了,只是没人教过怎么看。
有个前提先说明:状态码说的是 HTTP 请求本身,不代表页面内容一定正常。返回 200 但页面白屏的情况很常见,那是前端脚本的问题,跟状态码没关系。
四个数字的分工
第一位数字决定大类,这是理解状态码最快的方式。
| 开头 | 含义 | 问题通常出在 |
|---|---|---|
| 2xx | 成功 | 没出问题,不用管 |
| 3xx | 重定向 | 地址变了,服务器让你换个地方取 |
| 4xx | 客户端错误 | 请求本身有问题:地址错、没权限、参数不对 |
| 5xx | 服务器错误 | 请求没问题,是服务器自己处理失败了 |
知道这条,排查方向基本就定了。看到 4 开头,先怀疑地址和参数;看到 5 开头,别在自己代码里翻半天,去看服务端日志。
4xx:先检查请求这边
404 Not Found
地址上没这个东西。可能的情况有几种:链接本身就是错的(少写一段路径、拼错了单词)、文件被删了或改名了、或者是应用路由没配好。
如果这个地址昨天还好好的,今天 404,那就要去问最近谁动过部署或改过路由。如果是别人的外链点进来 404,那是对方抄错了地址,你只需要确认自己的地址没变。
403 Forbidden
东西在,但不给你看。这是 403 和 404 最关键的区别:403 说明服务器认得出这个地址,只是拒绝了你的请求。
常见成因包括目录权限不对、IP 被限制、请求缺少必要的认证信息(比如 Cookie 过期),还有一种是服务器配置里明确禁掉了这类文件。排查的时候先看服务器日志里的具体原因,Nginx 会写清楚是权限问题还是规则拦截。
400 Bad Request
请求格式服务器读不懂。接口调试时最常见的原因是参数缺失、JSON 格式写错(比如多了个逗号)、或者请求头里的 Content-Type 没对上。
遇到 400 不用瞎猜,把请求体完整贴出来从头看一遍,通常一眼就能发现。
401 和 403 别搞混
401 是"你没说你是谁",需要先登录或补上凭证;403 是"我知道你是谁,但你没这个权限"。接口返回 401 就去检查 Token 有没有带上、有没有过期;返回 403 就要看账号权限配置对不对。
5xx:问题在服务端
500 Internal Server Error
一个笼统的说法:服务器处理请求时崩了,但没给出更具体的原因。真正的信息在服务端的错误日志里,它一般会记下具体的异常堆栈。
几种高频成因:数据库连接失败、代码里没捕获的异常、依赖的服务不可用、配置文件写错了。这类问题前端帮不上忙,也别在浏览器端反复刷新,直接去后端日志里找堆栈。
502 Bad Gateway
这个错误值得单独讲,因为它经常被误解。502 表示最前面那个反向代理(Nginx、云负载均衡之类)能正常工作,但它连不上后面的应用进程。
换句话说,你的 Nginx 是活的,后面的应用死了或者没起来。所以看到 502 的第一件事是上服务器确认应用进程还在不在,而不是去改 Nginx 配置。进程频繁挂掉的,去查它的崩溃日志和内存占用。
504 Gateway Timeout
应用进程还活着,但处理时间超过了网关等待的上限。数据库慢查询、调用第三方接口卡住、大批量数据处理,都可能导致 504。
区分 502 和 504 有个简单的判断方法:502 是"人不在",504 是"人在但忙不过来"。前者查进程,后者查性能。
503 Service Unavailable
服务器暂时没法处理请求,通常是过载、正在重启,或者处在维护状态。如果配置得当,这类响应里会带一个 Retry-After 头,告诉客户端多久之后再试。
3xx:改地址的时候最容易出错的地方
301 和 302 都是跳转,区别在于永久还是临时,而这个区别对搜索引擎来说很重要。
301 是永久跳转,搜索引擎会把原地址积累的权重转到新地址上。换域名、改 URL 结构、HTTP 迁 HTTPS,都该用 301。
302 是临时跳转,权重仍然算在原地址上。临时活动页、维护期间的跳转用它合适。
实际工作中最容易踩的坑,是把该用 301 的地方写成了 302。结果就是新地址迟迟不被收录,搜索流量一直挂在旧地址上。反过来,临时跳转用了 301,浏览器会把跳转缓存得很死,等你想改回来的时候,用户还在被带到旧页面。
额外提醒一句:跳转链不要太长。A 跳 B、B 跳 C、C 再跳 D,除了拖慢速度,搜索引擎对长跳转链的处理也不友好。能一步到位就别绕。
怎么快速查到状态码和响应头
浏览器开发者工具的 Network 面板是最顺手的。打开它,刷新页面,点任意一条请求,Status 一栏就是状态码,Response Headers 里能看到服务器返回的所有头信息。想看跳转的完整过程,勾上 Preserve log,否则页面跳转时记录会被清掉。
需要脱离浏览器测试的时候,命令行里的 curl 更直接。curl -I 只发 HEAD 请求,拿到的就是状态行和响应头,不下载正文,看跳转关系很快。
# 只看响应头,不下载内容
curl -I https://example.com
# 显示完整跳转过程
curl -IL https://example.com
# 带上 Cookie 测试需要登录的接口
curl -I -H "Cookie: session=xxx" https://example.com/api/user
排查线上问题时有个小技巧:如果怀疑是缓存或 CDN 在捣鬼,在 curl 里加一个随机的查询参数(比如 ?t=123),就能绕过部分缓存看到源站的真实响应。
排查顺序建议
把上面这些揉成一个可以照做的流程:第一步看状态码第一位数字,定大方向;第二步看服务端错误日志,那里有最具体的线索;第三步如果涉及跳转,用 curl 把整条跳转链打出来;最后再考虑缓存和 CDN 的影响。
顺序别搞反。见过太多人在浏览器里反复强刷、清缓存折腾半小时,最后发现是后端服务根本没启动。
常见问题 FAQ
404 和 403 有什么区别?
404 是资源不存在,服务器明确告诉你这个地址上没有东西。403 是资源存在但拒绝访问,服务器认得出这个地址,只是不让你看。判断方法很简单:403 说明地址是对的,权限或配置有问题;404 说明地址本身就是错的,或者文件被删了。
500 和 502 有什么区别,该找谁?
500 是服务器内部错误,通常出在后端代码或应用运行环境,该找后端开发。502 是网关错误,说明反向代理(Nginx 等)连不上后面的应用进程,多半是应用挂了或没启动,该找运维或后端确认进程状态。504 是网关超时,应用还活着但响应太慢,通常是数据库慢查询或外部接口拖住了。
为什么网站返回 200 但页面是空白的?
状态码只表示这次 HTTP 请求本身成功,不代表页面内容正常。常见情况:前端 JavaScript 报错导致渲染中断、接口返回了空数据、或者是单页应用的路由没匹配上。这类问题要看浏览器控制台的报错,光看状态码看不出来。
301 和 302 跳转对 SEO 有影响吗?
有,而且区别很大。301 是永久跳转,搜索引擎会把原地址的权重转移到新地址,换域名、改路径用 301。302 是临时跳转,权重仍留在原地址,适合活动页、临时维护页。把该用 301 的地方写成 302,会让新地址迟迟收录不上去。
