404 Not Found
404 实际上代表什么、为什么它和 410 不一样,以及遇到意料之外的 404 时该检查哪些地方。
在你的浏览器中运行
点一下代码即可复制。
4xx · 客户端错误
请求本身有问题,或是不被允许。改变请求内容可能会有帮助。
| 代码 | 意义 |
|---|---|
| Bad Request | 服务器根本看不懂这个请求。 |
| Unauthorized | 你尚未通过身份验证,服务器不知道你是谁。名字取错了:401 的意思是「未验证身份」,「没有权限」是 403。401 必须带上 `WWW-Authenticate` 标头。 |
| Forbidden | 服务器知道你是谁,但你就是不能拿到这个东西。重新登录没有用。如果连「这个资源存在」本身都算机密,回 404 才是比较安全的做法。 |
| Not Found | 这个地址上没有任何东西。它完全没有说这东西曾经存不存在。如果你确定它永远消失了,请用 410。 |
| Method Not Allowed | 这个地址存在,但不接受这个方法。响应必须列出可用的方法。 |
| Conflict | 请求与目前的状态冲突,例如你正在修改的其实是旧版本。 |
| Gone | 它曾经存在,而且是刻意被移除的,不会再回来。 |
| I'm a teapot | 1998 年愚人节的玩笑,然后就再也没消失过。 |
| Unprocessable Content | 格式没问题,但语义上是错的——例如合法的 JSON 里有不合法的字段。 |
| Too Many Requests | 你被限流了,`Retry-After` 会告诉你什么时候可以再来。 |
没有符合的状态码。
它实际上说了什么
404 只说了一件事:这个地址上没有东西。
它刻意不说这里曾不曾有过、之后会不会有,也不说如果有的话你有没有资格看。这种含糊是特意 设计的——正是它让服务器可以隐藏某样东西的存在,而不必承认自己在隐藏。
该用 404 还是 410
如果你确定那个东西曾经存在、而且是被刻意移除的,410 Gone 是更好的答案。它是一个更强 的陈述:不是「我找不到」,而是「这东西是刻意消失的」。
实际差别在爬虫。搜索引擎会把 404 当成可能只是暂时的,还会再回来看一阵子;410 则告诉它们 可以停了,页面也会更快从索引中移除。如果你是有意识地要淘汰一批网址,410 才是你真正的意思。
其他时候用 404 就好——而那是大多数情况,因为大部分服务器根本分不出「从来没有过」和「去年 被删掉了」。
遇到不该出现的 404 时
大致按照「后来发现真的是这个原因」的频率排列:
- 结尾的斜线。
/about和/about/是两个不同的网址,很多服务器只处理其中一个。 - **大小写。**路径在 Linux 服务器上区分大小写,在 macOS 和 Windows 上不区分,所以本机 正常的连结到了正式环境就 404。
- **路由存在,但方法不对。**有些框架在对「只接受 GET 的路由」发 POST 时会回 404,而不是 正确的 405 Method Not Allowed,这会把你引导到完全错误的方向去找问题。
- 改写或转址规则比你预期的更早就被命中了。
- 单页应用程序没有服务器端的 fallback:在应用程序里点过去正常,直接开网址就 404。
404 页面本身也该是 404
自订错误页是好事,但用 200 状态送出它就不是了——那叫做「软 404」,等于告诉每一个爬虫 说:这页满是「找不到」的内容是值得收录的真实内容。状态码要跟着页面一起设对。
也让那一页真的有用:一个搜索框,加上一个回到该网址所属区块的连结,胜过一句道歉。