404 表示「服务器收到了请求,但找不到这个资源」。 它是个正常响应,不是错误——和 500 完全不是一类。
上一节 403 是「有但不能看」,这一节 404 是「没有」。 这一对经常被故意混用,背后是安全与可用性的取舍。
一、404 与 410
410 Gone 表示「曾经有,永久没了」。
它比 404 更明确,搜索引擎看到 410 会更快删掉收录,而不是反复来试探。
Demo 里三个路径分别回 200、404、410,正文长度各不相同——其中 404 的正文 24 字节(一句中文提示),
410 的 12 字节。
什么时候用 410?下架商品、删除的文章、废弃的接口。
但要注意:一旦说「永久没了」,就别让它再回来,否则搜索引擎会困惑。
二、两个常见误用
误用一:权限不足回 404。这是安全模糊化,没错,但要和 403 的使用保持一致。 同一个系统里有的地方 403、有的地方 404,攻击者反而能从差异里推断。 误用二:接口出错全回 404。 这会把「路由没匹配」「业务对象没找到」「上游服务挂了」三种完全不同的情况混成一个码, 排查时无从下手。 正确做法:路由没匹配用 404,业务对象没找到也用 404,但正文里要区分(或者用不同错误码); 上游挂了用 502/504。
三、404 页面的价值
从产品角度看,404 页面是唯一一个用户不想要但一定会看到的页面。 好的 404 页会做三件事:承认找不到、给出可能的去处(首页、搜索、热门链接)、保持品牌一致性。 从工程角度看,404 的日志价值更高: 大量 404 往往意味着链接腐烂、改版没做重定向、或者有人在扫描。 按路径聚合看,前十个 404 路径基本就能定位问题。 还有一个细节:默认的服务器 404 页会暴露服务器类型和版本,自定义 404 页是第一道信息隐藏。
四、动手 Demo:200、404、410 三个响应对照
服务端按路径返回三种状态,分别打状态行和正文长度。
if path == u'/gone':
return (u'HTTP/1.1 410 Gone', [(u'Content-Type', u'text/plain')],
b'gone forever')
if path == u'/exists':
return (u'HTTP/1.1 200 OK', [(u'Content-Type', u'text/plain')], b'here')
return (u'HTTP/1.1 404 Not Found',
[(u'Content-Type', u'text/html; charset=utf-8')],
u'<h1>页面不存在</h1>'.encode())
实跑输出:
--------------------------------------------------------------------
404 Not Found:没这个东西
--------------------------------------------------------------------
/exists HTTP/1.1 200 OK,正文 4 字节
/nothing HTTP/1.1 404 Not Found,正文 24 字节
/gone HTTP/1.1 410 Gone,正文 12 字节
404 的含义 服务器收到了请求,但找不到这个资源
404 不是错 它是正常响应,跟 500 完全不是一类
410 与 404 410 表示「曾经有,永久没了」,比 404 更明确
为什么要区分 搜索引擎看到 410 会更快删掉收录
两个常见误用:
① 权限不足时回 404 而不是 403——这叫「安全模糊化」,
目的是不让攻击者探测哪些资源存在,很多系统故意这么做。
② 接口出错全回 404——那是把「路由没匹配」和「业务没找到」混在一起了。
/exists 200 OK,正文 4 字节、/nothing 404 Not Found,正文 24 字节、
/gone 410 Gone,正文 12 字节——三个码都有正文,404 不是「没有响应」。
这正是新手常犯的错:以为 404 就是「空响应」。
实际上它可以有完整的 HTML 页面、甚至可以是几十 KB 的品牌页。
410 与 404 410 表示「曾经有,永久没了」,比 404 更明确——搜索引擎对这两个码的处理不同,
这是它存在的全部理由。
30 秒实验
- 把 404 的正文换成很大的页面,看客户端会不会正常渲染(会)。
- 让 404 响应带
Cache-Control: max-age=3600,想想合不合理(不合理,资源回来了用户也看不到)。 - 用
curl -I请求一个不存在的路径,看响应头里暴露了什么信息。
常见误区
- 「404 是错误」——它是正常响应,属于 4XX 但不算故障。
- 「404 表示服务器挂了」——服务器好好的,只是没有那个资源。
- 「所有找不到都该 404」——废弃资源用 410 更准确。
自测三问(点开对答案)
1. 404 与 410 的区别? —— 404 是「找不到」,410 是「曾经有、永久没了」。搜索引擎处理不同。 2. 为什么有的系统把无权限回成 404? —— 安全模糊化,避免攻击者通过状态码差异判断资源是否存在。 3. 大量 404 日志说明了什么? —— 链接腐烂、改版没做重定向,或者有人在扫描探测。4XX 讲完了。最后一节进 5XX:服务端自己的问题。
- ☐ (本节完,下一节 4.5.1 500 Internal Server Error)