跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何通过 Content Index API 允许浏览器异步索引离线可用的原始 DOM 页面

Content Indexing API 是元数据注册器而非索引器,仅向浏览器 UI 暴露可点击条目;它不读/验/触发缓存,add() 调用成功仅表示“挂名”,离线加载依赖 Service Worker 的 fetch 事件命中缓存 HTML 响应。 Content Indexing API 本身 不支持异步索引原始 DOM 页面 ,它也不处理“原始 DOM”——它只注册已缓存的、完整响应的 URL(通常是 HTML 文档),且必须满足严格前提。所谓“异步索引”是常见误解:API 的
add()
调用是同步 JavaScript 方法,是否生效完全取决于底层缓存是否就绪、路径是否匹配、状态码是否为 200。 真正起作用的是 缓存先行 + 索引声明 的配合逻辑,而非 API 自身具备异步能力。 ✅ 正确理解 Content Indexing API 的定位 它不是索引器,而是 元数据注册器 :仅向 浏览器 UI(如 Chrome 的「离线页面」列表)暴露一条可点击条目 它不读缓存、不验缓存、不触发缓存;调用
index.add()
成功 ≠ 页面已缓存,只是“挂了个名” 浏览器点击该条目时,会发起标准导航请求(
mode: 'navigate'
),能否离线加载,全靠 Service Worker 的
fetch
事件能否命中并返回缓存的 HTML 响应 ✅ 确保目标页面是“离线可用的原始 DOM 页面” 原始 DOM 页面指服务端返回的、未被 JS 动态渲染的完整 HTML 文档(即 SSR 或静态生成页)。要让它离线可用,需: 在 Service Worker 中明确缓存 HTML 响应(不能只缓存 JSON 或 JS) 缓存响应的
status
必须为
200
(重定向、404、500 均不可索引) 响应头需含
content-type: text/html
缓存路径(如
/article/123/
)必须与
index.add({ url: '...' })
中的
url
完全一致 (含尾部斜杠、大小写、查询参数) 示例缓存操作:
caches.open('pages-v1').then(cache => cache.addAll([ '/article/123/', '/offline.html', '/' ]) );
✅ 在合适时机注册索引(非 install 阶段)
install
阶段缓存可能尚未完成,
fetch
中动态缓存又难保证顺序。推荐在
activate
后检查缓存并注册: ZERO浏览器 一款PC端AI智能浏览器 下载
self.addEventListener('activate', event => { event.waitUntil((async () => { const cache = await caches.open('pages-v1'); const response = await cache.match('/article/123/'); if (response && response.status === 200) { const reg = await navigator.serviceWorker.getRegistration(); if (reg.index) { await reg.index.add({ id: 'article-123', url: '/article/123/', title: '标题已缓存', description: '原始 HTML 页面', icons: [{ src: '/icon.png', sizes: '192x192', type: 'image/png' }] }); } } })()); });
✅ 让点击索引条目真正加载离线 DOM 用户点击列表项后,浏览器发起导航请求。Service Worker 必须拦截并返回缓存 HTML:
self.addEventListener('fetch', event => { if (event.request.mode === 'navigate') { event.respondWith( caches.match(event.request) .then(response => response || fetch(event.request)) ); } });
关键点: 必须监听
mode === 'navigate'
,不是
destination: 'document'
(旧写法已不推荐)
caches.match()
要能精确匹配到你缓存的 URL(注意路径规范) 不建议 fallback 到网络,否则离线时会失败;若需优雅降级,应预置
/offline.html
并确保它也在缓存中 不复杂但容易忽略

相关文章