你的网站用了Service Worker,百度蜘蛛真的进得来吗?
你刚给网站加了 Service Worker,首页秒开、离线能看,心里正美着——结果半夜刷百度搜自己品牌词,新页面压根没影儿。
别慌,不是百度拉黑了你,是那个“管家”可能没认出谁才是真客人。
Service Worker到底是个什么“门卫”?
它是个跑在后台的 JS 脚本,能拦下你网站发出的每一个网络请求。
比如用户点开一篇文章,这个脚本可以决定:
- 直接从本地缓存里拿旧内容(快)
- 还是老老实实去服务器要最新版(准)
但它和网页本身不在一个线程里,互不打扰。
所以问题来了:当百度蜘蛛来敲门时,开门的是这个“管家”,还是网页自己?
答案决定了蜘蛛看到的是你精心写的正文,还是一句冷冰冰的“请检查网络”。
百度官方到底是怎么说的?
百度搜索资源平台写得很清楚:蜘蛛会尝试渲染 JavaScript 页面,也支持不少动态能力。
但它没说过一句“我们完全兼容 Service Worker”。
因为百度的思路很实在:我尽量学着普通浏览器的样子去访问你的站。
你让用户用 Chrome 打开能正常看到全文,蜘蛛大概率也能;
可如果你的 Service Worker 把首页变成一张纯图片、或者只返回个 loading 动画,那蜘蛛就真卡在门口了。
哪些 Service Worker 操作会“挡住”百度蜘蛛?
我们帮几十个技术类、电商类、内容类网站排查过,下面这几种写法,最容易让蜘蛛迷路:
- 第一次访问就强制离线兜底:用户或蜘蛛头一回打开,Service Worker 立刻拦截所有请求,返回一个只有
<!DOCTYPE html><body>离线中...</body>的空壳页。蜘蛛连导航栏都看不到,自然爬不到第二页。 - 偷偷给百度 UA 返回简化版 HTML:比如检测到
Mozilla/5.0 (compatible; Baiduspider/2.0)就塞进去一个没 CSS、没 JS、连<main>都删了的极简版。这等于主动告诉百度:“别细看了,给你看个假的。” - 把整个 HTML 文件塞进缓存,半年都不换:你昨天发了新文章,但 Service Worker 还在固执地吐一个月前缓存的首页——蜘蛛抓到的永远是旧快照,新链接根本露不出脸。
一个真实案例:某程序员博客上线离线阅读功能后,连续三周新文章零收录。查下来发现,install 阶段就把 /index.html 整个缓存了,且没设更新逻辑。蜘蛛每次来,拿到的都是部署当天的首页,连“最新文章”栏目里的链接都是错的。改掉 HTML 缓存逻辑后,第二天就开始陆续被收录。
如何安全地使用 Service Worker,又不影响 SEO?
核心就一条:对真实用户,你使劲优化体验;对百度蜘蛛,你装作啥也没干。
方法一:HTML 请求必须走网络优先
在 fetch 事件里,明确区分资源类型:
- 遇到
.html或关键 API,先fetch(url),失败了再 fallback 到缓存; - 图片、字体、CSS 这类静态资源,才放心用缓存。
方法二:彻底删掉任何 UA 判断逻辑
别写 if (request.headers.get('user-agent').includes('Baiduspider')) 这种代码。
蜘蛛不是特殊访客,它是你最挑剔的普通用户——禁用 JS、网速差、还爱刷新三次。
方法三:HTML 缓存?能不缓就不缓;非要缓,必须带版本号+自动清理
比如缓存名别叫 'pages',改成 'pages-v2';上线新版本时,新 Worker 启动立刻调用 caches.delete('pages-v1'),再 skipWaiting() 接管页面。
方法四:把关键链接“焊死”在初始 HTML 里
首页源码中,必须有真实的 <a href="/post/xxx">《今天搞懂了 Service Worker》</a>。
别指望靠 JS 渲染完再插入链接——蜘蛛不等。
怎么验证百度蜘蛛看到了什么?
别猜,直接看百度给你的“现场录像”。
打开百度搜索资源平台 → “抓取诊断” → 输入你的首页地址 → 点“开始抓取”。
等状态变成“抓取成功”,点开“抓取内容”,复制里面的纯文本。
再新开标签页,右键你的首页 → “查看网页源代码”,也复制一份。
两份文本并排打开,只比三样东西:
<title>里的标题对不对<h1>主标题有没有- 页面上最重要的 3~5 个
<a href="...">链接,是否都完整出现在抓取内容里
如果这些全在,说明 Service Worker 对蜘蛛透明;
如果缺了标题、少了链接、正文只剩“加载中…”,那就得立刻翻代码了。
今天下班前就能做的紧急检查清单
现在,打开你常用的浏览器,按顺序做这 4 步:
- 打开百度搜索资源平台(就是你平时提交 sitemap 的那个后台)
- 找到“抓取诊断”工具,输入你网站的首页 URL(比如
https://your-site.com/) - 点“开始抓取”,等它显示“抓取成功”后,点开“抓取内容”
- 右键你的网站首页 → “查看网页源代码” → 把两份文本粘贴到记事本里,对照上面说的三样东西(
<title>、<h1>、关键<a>)
如果发现明显缺失,马上打开你项目里的 sw.js,重点盯 self.addEventListener('fetch', ...) 里对 request.destination === 'document' 的处理逻辑——十有八九,就卡在这儿。