Chrome 54 中的 CacheQueryOptions 新增功能

如果您在 Service Worker 中或者通过 window.caches 直接在 Web 应用中使用 Cache Storage API,那么好消息:从 Chrome 54 开始,Chrome 54 将支持全套 CacheQueryOptions,让您能够更轻松地找到所需的缓存响应。

此时有哪些选项?

您可以在对 CacheStorage.match()Cache.match() 的任何调用中设置以下选项。如果未设置,它们都默认为 false(对于 cacheName,则为 undefined),并且您可以在对 match() 的单次调用中使用多个选项。

ignoreSearch

这会指示匹配算法忽略网址的搜索部分,也称为网址查询参数。如果您的源网址包含查询参数,例如用于分析跟踪,但在唯一标识缓存中的资源方面并不重要,这样做就会派上用场。例如,许多人都遭受过以下 Service Worker“gotcha”的攻击:

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache')
      .then(cache => cache.add('index.html'))
  );
});

self.addEventListener('fetch', event => {
  // Make sure this is a navigation request before responding.
  if (event.request.mode === 'navigation') {
    event.respondWith(
      caches.match(event.request) || fetch(event.request)
    );
  }
});

当用户直接导航到 index.html 时,这种代码会按预期运行,但如果您的 Web 应用使用分析工具提供商来跟踪入站链接,而用户又导航到 index.html?utm_source=some-referral,该怎么办?默认情况下,将 index.html?utm_source=some-referral 传递给 caches.match() 不会返回 index.html 的条目。但是,如果将 ignoreSearch 设置为 true,则无论设置何种查询参数,您都可以检索预期的缓存响应:

caches.match(event.request, {ignoreSearch: true})

cacheName

如果您有多个缓存,并且您希望将响应存储在一个特定缓存中,cacheName 会派上用场。使用此参数可以提高查询的效率(因为浏览器只需要检查一个缓存而不是所有缓存),并且当多个缓存可能将该网址作为键时,您可以检索针对给定网址的特定响应。cacheName 仅在与 CacheStorage.match()(而非 Cache.match())一起使用时才有效,因为 Cache.match() 已对单个已命名的缓存执行操作。

// The following are functionally equivalent:
caches.open('my-cache')
  .then(cache => cache.match('index.html'));

// or...
caches.match('index.html', {cacheName: 'my-cache'});

ignoreMethodignoreVary

ignoreMethodignoreVaryignoreSearchcacheName 略显小众,但它们有着特定的用途。

ignoreMethod 允许您将具有任何 methodPOSTPUT 等)的 Request 对象作为第一个参数传入 match()。通常,系统仅允许发出 GETHEAD 请求。

// In a more realistic scenario, postRequest might come from
// the request property of a FetchEvent.
const postRequest = new Request('index.html', {method: 'post'});

// This will never match anything.
caches.match(postRequest);

// This will match index.html in any cache.
caches.match(postRequest, {ignoreMethod: true});

如果设置为 true,则 ignoreVary 表示将执行缓存查询,而不会影响缓存响应中设置的任何 Vary 标头。如果您知道自己所处理的不是使用 Vary 标头的缓存响应,则无需担心设置此选项。

浏览器支持

CacheQueryOptions 仅与支持 Cache Storage API 的浏览器相关。除了基于 Chrome 和基于 Chromium 的浏览器之外,目前仅限于 Firefox,因为 Firefox 已原生支持 CacheQueryOptions

开发者如果想在低于 54 的 Chrome 版本中使用 CacheQueryOptions,可以使用由 Arthur Stolyar 提供的 polyfill