先给结论:只有当两个请求在同一时刻、同一出口 IP、同一 URL 串下,仅切换设备或登录状态这一个变量时,返回内容的差异才可以归因到设备或身份;否则你看到的更可能是缓存、CDN 节点、A/B 实验或地域分流造成的偶然差异,不能直接当作死链检测工具的漏报。下面说明什么条件下结论成立,以及什么情况会让它失效。
死链检测工具通常以单一身份、单一 UA、单一网络出口批量请求。当它报 200,而你用手机或已登录账号打开同一地址却看到 404 或跳转时,两者不是同一实验。要让对照成立,至少固定四项:请求时间窗口(几分钟内)、出口网络(同一机房或同一代理)、完整 URL(含查询串、尾斜杠、大小写)、请求方法。任何一项变化都可能单独解释差异。
实际动作:用 curl -I 加 -H "User-Agent: ..." 和 -b "cookie=..." 各发一次请求,记录状态码、Location、Vary、Cache-Control 与响应体长度。如果两次只有 UA 或 Cookie 不同,其余相同,那么状态码分叉才值得继续追。这个动作的结果决定下一步:若 Vary 里出现 User-Agent 或 Cookie,说明服务端主动按身份分流,工具的单身份结果天然只覆盖一部分。
最容易被忽略的反例是边缘缓存把旧响应喂给了其中一个身份。假设同一 URL 在未登录时命中 CDN 的 404 缓存,而已登录请求绕过缓存回到源站拿到 200,此时差异来自缓存键(cache key)而不是登录状态本身。判断线索:对比两个响应的 Age、X-Cache 类头部,或对同一身份连续请求两次,看第二次是否变成另一个结果。如果同一身份两次结果都不一致,那设备或登录就不是主因。
另一个反例是URL 表面相同但实际不同:移动端可能被重写到 /m/ 前缀,登录后可能带上会话查询串。这类情况下死链检测工具报的地址与你浏览器地址栏的地址已经不是同一资源,对照失去意义。此外,A/B 实验、灰度发布、多机房源站也会让同一身份在不同时间拿到不同内容,与设备无关。
Vary 声明了该头部。此时工具需要补一个登录态爬取配置,否则未登录路径的 404 不能代表真实用户。这三类的处理顺序不同:身份类要改抓取配置,设备类要改重定向规则或检测目标,环境类要改缓存策略。判断错类别,后续修复会打偏。
假设某商品页对未登录用户返回 200,对已登录但无权限用户返回 403 并展示“商品已下架”。死链检测工具以匿名身份抓取,全部报 200,看起来没有死链。若只凭这个结果就判断“无死链”,会漏掉真实用户遇到的软 404 式体验。正确做法是把登录态纳入一次抽样对照:取同一批 URL,分别用匿名和登录身份各抓一次,比较状态码与页面关键文案。若登录态出现 403 或“不存在”文案,而匿名态是 200,说明该地址对部分用户已失效,需要按身份维度重新界定死链范围。
注意这个例子成立的前提是登录态能稳定复现,且两次抓取在短时间内完成。若登录态本身不稳定或缓存介入,结论不成立。
先做小样本对照,确认差异属于身份、设备还是环境,再决定是否把登录态或移动 UA 加入常规检测。不要直接把单一身份的批量结果当作全量结论,也不要用 robots.txt 限制或站点地图提交来代替对实际用户路径的验证——前者只约束抓取,后者不保证收录,都无法回答“某个身份看到的是不是死链”。
规模化时会出现例外:样本里成立的规律,在长尾 URL、带参数地址或跨机房请求上可能失效。因此每次扩大检测范围后,都应保留一组已知身份差异的对照样本,用来校验工具输出是否仍然可信。若对照样本本身开始漂移,先停下扩量,回到缓存键与身份分流这两条线索重新定位,再决定下一步检测范围。