站点上线了一套自定义探活逻辑,对所有 HEAD 请求直接返回 200 空响应。上线一周后新文章收录几乎停摆,GSC 的网址检查显示已抓取但内容为空,日志里能看到蜘蛛先发 HEAD 拿到 200,后面的 GET 请求就再也没有出现。

一开始怀疑是「HEAD 返回的 Content-Length 与实际 GET 内容不一致 蜘蛛判成异常」,查了一圈,方向不对。

真正麻烦的地方在于,几个原因的现象几乎一样。HEAD 走的是静态占位分支 没有真正经过路由和模板渲染。少数情况下是探活规则用 location = / 精确匹配 把蜘蛛的探测请求一起截住。

不容易想到的是,CDN 缓存了 HEAD 的空响应 后续 GET 命中同一份缓存。

手工发一次 HEAD 看响应头和长度

curl -sI https://www.example.com/article/123.html

再发 GET 对比两次的状态与长度

curl -s -o /dev/null -w '%{http_code} %{size_download}\n' https://www.example.com/article/123.html

随后检查 Nginx 里有没有为 HEAD 单独写的分支

grep -n 'if ($request_method' /etc/nginx/conf.d/*.conf

等前面都确认过,再让 HEAD 复用 GET 的响应头而不是空响应

proxy_cache_bypass $http_if_none_match;

恢复的判定其实很直接。统一之后 HEAD 与 GET 返回的 Content-Length 一致,日志里蜘蛛的 HEAD 后面紧接着就是 GET,新文章第二天就有抓取记录。

这里还有个坑。探活接口不要返回假的 200,蜘蛛对 HEAD 和 GET 的一致性很敏感,两边对不上会直接降低抓取意愿。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189