现场是这样的。推送脚本为了省带宽给请求体加了 Content-Encoding: gzip,一次提交 800 条 URL,必应接口回 415 Unsupported Media Type,未压缩时同样的数据能正常返回 200。
中间走过弯路,把「中间的反向代理重复压缩了一次,Content-Length 对不上」当成主因,改完现象没变。
真正麻烦的地方在于,几个原因的现象几乎一样。IndexNow 接口只接受 application/json 明文,不解析压缩体;脚本把 gzip 头写进了请求但响应体没解压,错误信息被吞掉;批量超过一万条后服务端提前拒绝,和压缩头混在一起不好区分。
去掉压缩头重发同一批数据对比返回码
curl -s -X POST 'https://api.indexnow.org/indexnow' -H 'Content-Type: application/json; charset=utf-8' --data-binary @urls.json -w '%{http_code}\n'
再往下确认请求头里没有残留 Content-Encoding
curl -v -X POST 'https://api.indexnow.org/indexnow' -H 'Content-Type: application/json' -d @urls.json 2>&1 | grep -i encoding
接着把批次拆到 500 条以内再观察
split -l 500 urls.json batch_
末了在脚本里对 415 单独记日志并停止重试
if code == 415: log('body not compressed'); break
别只看报错消失,验证要多做一步。去掉压缩头后同一批 URL 返回 200,响应体里 invalid 为 0,随后两天必应抓取日志出现这批地址。
补一句。接口返回 415 和 400 的处理方式不同,前者是格式问题重试无用,无限重试只会把配额耗光。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
