如何从Javascript中检查浏览器是否缓存了资源?

4

有没有一种方法可以在不下载资源的情况下检查浏览器是否缓存了资源?大部分问题和答案都比较老旧,我相信现在情况已经有所改变了,可能存在更好的方式。

2个回答

4
您可以利用 fetch API 及其对应的 AbortController 来实现这个功能并保留一定的误差(预期错误负数)。
具体操作是,在需要获取的资源上附加一个信号(signal),再使用 fetch 获取该资源,并设置一个短暂的超时时间,例如4ms。如果在规定的时间内获取到了资源,则说明它被完全缓存了。如果获取被中止,则可能未被缓存。以下是一些示例代码:
      async checkImageCached(url, waitTimeMs = 4) {
        const ac = new AbortController()
        const cachePromise = fetch(url, {signal: ac.signal})
          .then(() => true)
          .catch(() => false)
        setTimeout(() => ac.abort(), waitTimeMs)
        return cachePromise
      }

1
请将以下与编程相关的内容从英文翻译成中文。只返回翻译后的文本:不要下载资源 - Jaromanda X
@JaromandaX 它被迅速中止,因此没有被下载。 - Seaskyways
你觉得 setTimeout 能在4毫秒内触发吗?我记得20毫秒是最小可用时间(不过那是几年前的事了)。 - Jaromanda X
2
都好:p 我从这个答案中了解到了AbortController,所以+1:p 是的,你建议后我确实尝试了一下,并且考虑到使用console.log的延迟,4毫秒的超时在4或5毫秒触发! - Jaromanda X

3

目前只支持Firefox浏览器,不过另一个选项是使用only-if-cached,虽然它只适用于同源请求(因为它需要mode:'same-origin'):

fetch(urlOnSameOrigin, { mode: 'same-origin', cache: 'only-if-cached'})
  .then((response) => {
    if (response.ok) {
      console.log('Cached');
    } else if (response.status === 504) {
      console.log('Not cached');
    }
  })
  .catch(() => {
    console.log('Network error');
  });

only-if-cached — 浏览器在其HTTP缓存中查找匹配的请求。

  • 如果有匹配(新鲜或陈旧),则它将从缓存中返回。

  • 如果没有匹配,则浏览器将响应504网关超时状态。


是否需要“同源”? - Seaskyways
@Seaskyways 是的,看起来是这样的,这真是令人遗憾,因为一些跨站资源没有CORS限制,可以通过JS访问。 - CertainPerformance
我认为你也可以使用ETag头来完成这个操作,这样只有在文件内容发生变化时才会更新缓存。 - Anderson Green

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接