现场是这样的。为了把 key 文件放到 CDN 上,提交时加了 keyLocation 字段,写的是 https://cdn.example.com/indexnow-key.txt。接口一直返回 403,浏览器直接访问这个地址是 200,内容也只有一个 32 位字符串。

中间走过弯路,把「key 文件末尾多了换行或 BOM,与提交的 key 不完全相等」当成主因,改完现象没变。

把日志和配置对完,能解释这个现象的基本就这几处。keyLocation 的域名必须与提交的 host 同源,跨域直接判未验证;CDN 返回的 Content-Type 带 charset 参数,被严格校验拒绝;提交的 host 带 www,keyLocation 写在裸域,被当成两个站点。

动手时先对比提交值与文件原始字节

curl -s https://cdn.example.com/indexnow-key.txt | xxd | tail -3

然后确认响应头没带多余参数

curl -sI https://cdn.example.com/indexnow-key.txt | grep -i content-type

再往下把 key 文件和页面放到同一域名同一目录

curl -s https://www.example.com/indexnow-key.txt

剩下的就是用最短请求复验一次

curl -s -o /dev/null -w '%{http_code}\n' -X POST https://api.indexnow.org/indexnow -H 'Content-Type: application/json' -d '{"host":"www.example.com","key":"xxx","urlList":["https://www.example.com/p/1"]}'

怎么算真的好了,看的是同一批现象。返回码从 403 变成 202,站长工具的 IndexNow 记录显示验证通过,随后能看到抓取。

容易忽略的是,keyLocation 只是备用校验地址,能同域就同域,跨域省下的那点带宽不值得。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189