内容发出去还在等收录:IndexNow 协议与 Bing Webmaster 的即时提交接入规范
适用读者:负责外贸独立站的技术与 SEO 同学,站点跑在 .NET 上,Bing 带来的海外流量不能忽视,想搞清楚 IndexNow(即时索引协议)到底怎么接、接了会不会被判定滥用。
去年 11 月接手一个外贸独立站的技术支持,站点日均上新 30 个 SKU 页,sitemap 每天自动生成一次,但 Bing 的收录中位延迟长期卡在 7 到 14 天。运营负责人老周在周会上原话是:"产品页发出去两个星期,客户拿型号词去搜,连影子都没有,询盘全被同行截走了。"我们把发布链路改造成 IndexNow 推送加 Bing Webmaster API 兜底,今年 3 月拉了四周数据,收录中位延迟降到 26 小时。整个改造后端代码不到 150 行,难点不在写代码,而在协议细节和提交频次的拿捏。这篇文章把接入规范逐条拆开讲。
sitemap 为什么等不来快收录
sitemap 本质上是一份被动提交的 URL 清单。搜索引擎的抓取调度器会周期性读取它,但什么时候真正派爬虫来抓,完全取决于对方的抓取预算(Crawl Budget)分配。对中小体量的独立站,Bing 分配的抓取频次很保守,新页面往往要排好几轮队列。
这里有个容易被忽略的时间结构:sitemap 的更新周期加上调度器的轮询周期,再算上页面质量评估的排队时间,叠加起来就是那 7 到 14 天。你多发一篇产品页,这个延迟不会缩短半分,因为 sitemap 模式下站点对收录时机的干预能力约等于零。
IndexNow 把这个模式倒过来了:页面发布的那一刻,站点主动把 URL 推给搜索引擎端点,爬虫会尽快来抓。一个推、一个拉,时效差距就是这么来的。
IndexNow 协议规范逐条解读
接入步骤速览
前面把协议细节拆开讲了,这里把完整接入流程串成一张清单,每步标注对应正文的小节位置,照着走就行。
生成 key 文件并部署到站点根目录。用
openssl rand -hex 16生成 32 位十六进制 key,把文件名和文件内容都设为该 key,放到https://yourdomain.com/{key}.txt。注意文件末尾不要带换行,避免校验差异。(对应「IndexNow 协议规范逐条解读」的 key 文件验证部分)配置 CDN 缓存规则。给
*.txt这类路径在 CDN 上设置直通源站的缓存规则,防止 key 文件被缓存成旧内容导致 403。这一步不做,后面提交大概率会踩坑。(对应「IndexNow 协议规范逐条解读」的容易踩的规范细节部分)注册 Bing Webmaster Tools 并登记 sitemap。在 BWT 后台验证域名所有权,把 sitemap 地址登记好,作为引擎全量对账的基线;同时在 API 访问页生成 API Key,供后续 URL Submission API 兜底调用。(对应「Bing Webmaster Tools 的 API 和 sitemap 怎么配合」一节)
部署 .NET 8 后台推送服务。把
IndexNowPushService作为BackgroundService注册进宿主,消费商品发布事件,攒批后调用api.indexnow.org/IndexNow提交。注意host必须与 key 文件所在域名一致。(对应「.NET 8 后台发布事件触发提交」一节)验证提交与收录状态。上线后先看 BWT 后台的收录状态,确认新页面小时级进索引;若超过 72 小时未抓,用 BWT URL Submission API 兜底再提交一次。同时盯住 429 限流,触发就按指数退避。(对应「提交频次与滥用风险」一节)
IndexNow 是微软 Bing 和 Yandex 在 2021 年联合发起的开放协议,后来 Naver、Seznam 也加入了。规范本身不长,但每条都有坑,逐条过一遍。
key 文件验证。你要先生成一个 8 到 32 位十六进制字符的 key(比如a1b2c3d4e5f6),然后把它做成一个文本文件放在站点根目录:https://yourdomain.com/{key}.txt,文件内容就是这个 key 本身,不要带换行以外的任何多余字符。搜索引擎收到提交请求后,会回源拉这个文件,确认提交者真的控制这个域名。一个站点只需要一个 key,子域名可以共用,但协议要求 host 与 key 文件所在域名一致,跨域名提交会被拒。Linux 环境两行命令就能生成并落盘:
# 生成 32 位十六进制随机串作为 key# openssl -hex 输出正好符合 8-32 字符的协议要求KEY=$(openssl rand-hex16)# key 文件名和文件内容都必须与 key 完全一致# printf 不带 \n,避免文件末尾换行导致校验差异printf'%s'"$KEY">"/var/www/site/$KEY.txt"# 最后把 KEY 值记录到配置中心,提交端要用同一个值echo"IndexNow key:$KEY"提交方式。单条 URL 用 GET 就够,浏览器或 curl 直接访问即可:
https://api.indexnow.org/indexnow?url=https%3A%2F%2Fyourdomain.com%2Fp%2Fsku-123&key=你的key批量提交用 POST,往https://api.indexnow.org/IndexNow发一个 JSON,host填主域名,keyLocation可以省略(默认就是根目录 key 文件),urlList一次最多放 10000 条 URL,报文总大小不能超过 2MB。建议每批控制在 1000 条以内,引擎处理起来更快。api.indexnow.org是公共端点,提交一次会分发给所有接入协议的搜索引擎;你也可以直接用各家的专属端点,比如bing.com/indexnow。
响应码语义。这部分官方文档写得比较散,实测整理成表格:
| 状态码 | 含义 | 处理建议 |
|---|---|---|
| 200 OK | URL 已收到并验证通过,进入抓取队列 | 正常,不用重试 |
| 202 Accepted | 请求收到,key 尚未验证,稍后回源验证 key 文件 | 首次提交的正常现象,别当错误重发 |
| 400 Bad Request | 报文格式不合法 | 检查 JSON 结构和 URL 编码 |
| 403 Forbidden | key 文件校验失败,提交被判定无效 | 检查 key 文件内容与 URL 是否一致 |
| 422 Unprocessable Entity | URL 不属于 key 文件所在域名 | 只提交本站 URL |
| 429 Too Many Requests | 提交过于频繁,触发限流 | 退避后降低频次 |
容易踩的规范细节。URL 必须经过 URL 编码;urlList里不能混入其他域名的链接;key 文件如果被 CDN 缓存了旧内容,会导致 403,建议给*.txt这类路径在 CDN 上设置直通源站的缓存规则。我们在 12 月初就栽过一次,Cloudflare 把 key 文件缓存成了上一次部署的旧 key,提交全返 403,排查了一下午。
key 验证的机制拆解
这一节讲原理。IndexNow 的信任模型很朴素:它不搞账号体系,凭证只有一样:“你能控制某个路径下的某个文件”。引擎收到第一次提交时,会先回一个 202,同时异步去拉keyLocation指向的文件;拉到的内容与提交里声明的 key 一致,这个 host 才会被标记为已验证,后续提交直接走 200 的快车道。
验证通过之后,之前 202 状态下积压的提交不会丢,会一并入队。这个设计的好处是接入成本极低——不用注册账号、不用 API token——代价是 key 一旦泄露,任何人都能替你提交垃圾 URL 污染你的站点配额。所以 key 文件路径虽然公开,也别在公开仓库里到处贴。
整个推送链路放一张全景图:
.NET 8 后台发布事件触发提交
环境说明:.NET 8 Web API 项目,HttpClient走IHttpClientFactory注册,推送逻辑放在一个继承BackgroundService的常驻服务里,消费内存通道里的发布事件。依赖只有框架自带的System.Text.Json,不引第三方包。
// IndexNow 推送服务:消费商品发布事件,攒批后提交// 放在 BackgroundService 里跑,失败不影响商品发布主流程publicsealedclassIndexNowPushService:BackgroundService{// 批量上限 10000,实际攒 500 条就发,避免单批过大被限流// 日均 30 条的量级攒大批纯属浪费等待时间privateconstintBatchSize=500;privatereadonlyChannelReader<PublishedEvent>_reader;privatereadonlyIHttpClientFactory_httpFactory;privatereadonlyILogger<IndexNowPushService>_logger;publicIndexNowPushService(Channel<PublishedEvent>channel,IHttpClientFactoryhttpFactory,ILogger<IndexNowPushService>logger){// 从 DI 容器取通道读取端,事件由发布流程写入// 构造函数注入即可,不需要手动管理生命周期_reader=channel.Reader;_httpFactory=httpFactory;_logger=logger;}// ExecuteAsync 随宿主启动,宿主关闭时通过取消令牌优雅退出protectedoverrideasyncTaskExecuteAsync(CancellationTokenct){// 用一个缓冲区把短时间内的发布攒成一批varbatch=newList<string>(BatchSize);// WaitToReadAsync 无事件时挂起等待,不空转占 CPUwhile(await_reader.WaitToReadAsync(ct)){while(_reader.TryRead(outvarevt)){// 只推标准产品页,营销落地页走另一条链路// URL 要完整带上 https 前缀,相对路径会被判 400batch.Add($"https://shop.example.com/p/{evt.Sku}");// 攒满一批立刻发出,不等下一个时间窗口if(batch.Count>=BatchSize){awaitPushAsync(batch,ct);// 提交后清空缓冲区,开始攒下一批batch.Clear();}}// 批未攒满也要发,否则低峰期 URL 会滞留// 窗口期结束就落一次盘,保证准实时语义if(batch.Count>0){awaitPushAsync(batch,ct);batch.Clear();}}}privateasyncTaskPushAsync(List<string>urls,CancellationTokenct){// 按协议组装批量报文,host 必须与 key 文件所在域名一致varpayload=new{host="shop.example.com",key="a1b2c3d4e5f60718",urlList=urls};// 命名客户端在 Program.cs 里统一配置了 10 秒超时varclient=_httpFactory.CreateClient("indexnow");varresp=awaitclient.PostAsJsonAsync("https://api.indexnow.org/IndexNow",payload,ct);// 200 与 202 都算提交成功,区别只在 key 是否已验证过if(resp.StatusCodeisHttpStatusCode.OKorHttpStatusCode.Accepted)return;// 429 说明触发限流,退避 10 分钟再走重试队列// 重试任务交给独立的 Hangfire 队列,这里只负责记录if(resp.StatusCode==HttpStatusCode.TooManyRequests)_logger.LogWarning("IndexNow 限流,{Count} 条 URL 进入退避队列",urls.Count);else// 403/422 多半是 key 文件或域名不匹配,直接告警人工介入// 这两类错误重试无意义,先修配置再补交_logger.LogError("IndexNow 提交失败 {Code},批次 {Count} 条",(int)resp.StatusCode,urls.Count);}}两个实现细节值得说。一是BatchSize定在 500 而不是上限 10000,是因为日均 30 条的量根本攒不满大批,攒批窗口一长反而拖慢首条 URL 的时效,实测 5 分钟内的小批提交响应最快。二是不要在 HTTP 请求线程里同步等响应,推送失败不能阻塞商品发布主流程,这也是为什么放后台服务而不是发布接口里顺手调一下。
Bing Webmaster Tools 的 API 和 sitemap 怎么配合
IndexNow 负责增量,Bing Webmaster Tools(BWT)负责全量和可观测性,两条腿缺一不可。BWT 后台先把 sitemap 地址登记好,这是引擎做全量对账的基线;然后在 BWT 的 API 访问页生成一个 API Key,就能调用它的 URL Submission API,每天有单独的配额(普通站点每日数千条),和 IndexNow 的配额互相独立。
| 手段 | 定位 | 时效 | 适用场景 |
|---|---|---|---|
| sitemap | 全量清单,被动等待 | 天级到周级 | 兜底,保证不漏页 |
| IndexNow | 增量推送,事件驱动 | 小时级 | 新发布、内容更新的页面 |
| BWT URL Submission API | 手动/脚本补交 | 小时级 | IndexNow 异常时的兜底重试 |
这里要专门纠正一个流传很广的误解:Google 不支持 IndexNow。协议端点只会分发给接入的引擎(Bing、Yandex、Naver、Seznam),Google 的普通页面收录仍然依赖 sitemap 和 Google Search Console,它自家的 Indexing API 只对职位发布和直播视频开放。所以别指望接了 IndexNow,Google 那边的收录也跟着提速,那是两套体系。
Google 的收录机制与 Bing 是两套体系。Google 至今没有接入 IndexNow 协议,它的普通页面收录仍然依赖 sitemap 提交加 Google Search Console(GSC)的抓取调度。GSC 的 sitemap 提交本质上和 Bing 一样是被动等待,Google 的抓取预算分配更看重页面权重和站内链接结构,新页面从提交到收录通常要 3 天到两周,和 Bing 接入 IndexNow 之前的情况差不多。Google 也提供 Indexing API,但限制非常死:只对职位发布(JobPosting 结构化数据)和直播视频(BroadcastEvent)两类内容开放,普通产品页、博客文章都不在支持范围内,申请白名单也基本不会批。所以对外贸独立站来说,Google 侧没有"即时提交"的捷径,能做的只有把 sitemap 维护好、内链结构理顺、页面质量做扎实,然后接受它的收录节奏。
双轨策略建议:既然 Google 和 Bing 的收录机制完全不同,就不要指望一套方案通吃。建议把两条线分开管理——Bing 侧走 IndexNow 增量推送加 BWT URL Submission API 兜底,保证新页面小时级进 Bing 索引;Google 侧老老实实维护 sitemap 并在 GSC 里提交,同时把站内内链和页面质量做好,让 Google 的爬虫自己发现新页面。日常巡检时,Bing 看 BWT 后台的收录状态,Google 看 GSC 的"网页索引编制"报告,两边分开盯,别混在一起判断。这样 Bing 的时效优势能吃到,Google 的流量也不会因为误以为"接了 IndexNow 就万事大吉"而流失。
Naver、Seznam、Yandex 共享同一个 key 文件和提交规范,独立站如果做韩国或东欧市场,用公共端点api.indexnow.org一次提交就能覆盖这几家,不需要逐家对接,这也是这个协议对中小团队最实惠的地方。
提交频次与滥用风险
协议免费开放,但搜索引擎对滥用毫不客气。官方给的边界是:只提交新增或内容有实质变化的 URL,重复提交没变化的链接、提交已经 404 的页面、用脚本高频轰炸端点,都会触发 429 限流,严重的会拉低整个域名的提交信任度,后续请求被长期降级。
我们自己定的内部基线:单条 URL 从发布到提交至少间隔一次内容变更;批提交每 5 分钟最多一轮;429 之后指数退避,10 分钟、20 分钟、40 分钟,三轮之后进人工队列。上线头两周我们有个bug,商品改一次库存也会触发发布事件,等于同一 URL 一天被推十几遍,Bing 直接回了 429,把事件去重逻辑加上之后才恢复。频次这件事,宁可保守。
误区澄清或趋势预判
两个常见误区先摆平。误区一是"提交了就会收录"——IndexNow 只解决"尽快被抓",抓完之后页面质量评估、去重、排名照旧走搜索引擎自己的流程,低质量页面照样不收。误区二是"key 文件越隐蔽越安全"——key 本来就是公开验证用的,真正的安全边界是别泄露到能被第三方替你提交的程度即可,过度包装没有意义。
再往趋势上看一眼,即时提交这件事对 GEO(Generative Engine Optimization,生成式引擎优化)也有间接价值。AI 爬虫(GPTBot、ClaudeBot 这类)的抓取频次普遍比传统爬虫低得多,新页面进入 AI 语料的窗口期更长;而 Bing 的索引同时是 ChatGPT 搜索引用的数据源之一,IndexNow 把页面送进 Bing 索引的速度提上来,等于顺带压缩了页面被 AI 引擎发现的时间。对以外贸询盘为生的独立站,这个时间差有时就是订单差。
参考与延伸
- IndexNow 官方协议文档(key 规范、提交格式、响应码):https://www.indexnow.org/documentation
- Bing Webmaster Tools 产品与功能入口:https://www.bing.com/webmasters/about
- Bing Webmaster API 官方文档(URL Submission、sitemap 管理):https://learn.microsoft.com/en-us/bingwebmaster/
IndexNow、Bing Webmaster、收录提速、sitemap、独立站SEO、即时提交