概念与用法
目前,用户难以发现离线 Web 内容。内容索引允许开发者告知浏览器其特定的离线内容。这使得用户能够发现和查看可用内容,同时让开发者能够添加和管理这些内容。例如,新闻网站可以在后台预加载最新文章,或者内容流应用可以注册已下载的内容。
Content Index API 是 Service Worker 的一个扩展,它允许开发者在当前 Service Worker 的作用域内添加已缓存页面的 URL 和元数据。浏览器随后可以使用这些条目向用户显示离线阅读内容。作为开发者,你也可以在你的应用程序中显示这些条目。
索引条目不会自动过期。最好提供一个清除条目的界面,或者定期删除旧条目。
注意: API 支持索引对应于 HTML 文档的 URL。例如,缓存媒体文件的 URL 不能直接索引。相反,你需要提供一个显示媒体且支持离线的页面的 URL。
接口
- ContentIndex实验性
- 
提供注册离线可用内容的功能。 
- ContentIndexEvent实验性
- 
定义用于表示 contentdelete事件的对象。
其他接口的扩展
Content Index API 规范中指定了对 ServiceWorker 的以下添加,以提供使用内容索引的入口点。
- ServiceWorkerRegistration.index只读 实验性
- 
返回一个指向 ContentIndex接口的引用,用于索引已缓存的页面。
- contentdelete事件 实验性
- 
当内容被用户代理移除时触发。 
示例
以下所有示例都假定已注册 Service Worker。有关更多信息,请参阅 Service Worker API。
功能检测和接口访问
在这里,我们获取对 ServiceWorkerRegistration 的引用,然后检查 `index` 属性,该属性提供了对内容索引接口的访问。
// reference registration
const registration = await navigator.serviceWorker.ready;
// feature detection
if ("index" in registration) {
  // Content Index API functionality
  const contentIndex = registration.index;
}
添加到内容索引
在这里,我们以正确的格式声明了一个条目,并创建了一个异步函数,该函数使用 add() 方法将其注册到内容索引。
// our content
const item = {
  id: "post-1",
  url: "/posts/amet.html",
  title: "Amet consectetur adipisicing",
  description:
    "Repellat et quia iste possimus ducimus aliquid a aut eaque nostrum.",
  icons: [
    {
      src: "/media/dark.png",
      sizes: "128x128",
      type: "image/png",
    },
  ],
  category: "article",
};
// our asynchronous function to add indexed content
async function registerContent(data) {
  const registration = await navigator.serviceWorker.ready;
  // feature detect Content Index
  if (!registration.index) {
    return;
  }
  // register content
  try {
    await registration.index.add(data);
  } catch (e) {
    console.log("Failed to register content: ", e.message);
  }
}
检索当前索引中的条目
下面的示例展示了一个异步函数,该函数检索内容索引中的条目,并遍历每个条目,为界面构建一个列表。
async function createReadingList() {
  // access our service worker registration
  const registration = await navigator.serviceWorker.ready;
  // get our index entries
  const entries = await registration.index.getAll();
  // create a containing element
  const readingListElem = document.createElement("div");
  // test for entries
  if (entries.length === 0) {
    // if there are no entries, display a message
    const message = document.createElement("p");
    message.innerText =
      "You currently have no articles saved for offline reading.";
    readingListElem.append(message);
  } else {
    // if entries are present, display in a list of links to the content
    const listElem = document.createElement("ul");
    for (const entry of entries) {
      const listItem = document.createElement("li");
      const anchorElem = document.createElement("a");
      anchorElem.innerText = entry.title;
      anchorElem.setAttribute("href", entry.url);
      listElem.append(listItem);
    }
    readingListElem.append(listElem);
  }
}
取消注册已索引的内容
下面是一个异步函数,它从内容索引中移除一个条目。
async function unregisterContent(article) {
  // reference registration
  const registration = await navigator.serviceWorker.ready;
  // feature detect Content Index
  if (!registration.index) return;
  // unregister content from index
  await registration.index.delete(article.id);
}
以上所有方法都可以在 Service Worker 的作用域内访问。它们可以通过 `WorkerGlobalScope.self` 属性访问。
// service worker script
self.registration.index.add(item);
self.registration.index.delete(item.id);
const contentIndexItems = self.registration.index.getAll();
contentdelete 事件
当用户代理界面中的某个条目被移除时,Service Worker 会收到一个 `contentdelete` 事件。
self.addEventListener("contentdelete", (event) => {
  console.log(event.id);
  // logs content index id, which can then be used to determine what content to delete from your cache
});
contentdelete 事件仅在删除是由于与浏览器内置用户界面的交互而发生时触发。当调用 ContentIndex.delete() 方法时,不会触发此事件。
规范
| 规范 | 
|---|
| Content Index | 
浏览器兼容性
api.ContentIndex
加载中…
api.ServiceWorkerRegistration.index
加载中…