【问题标题】:How to check if a resource is cached by the browser from Javascript?如何检查资源是否被浏览器从 Javascript 缓存?
【发布时间】:2020-01-17 12:37:02
【问题描述】:

有没有办法在不下载资源的情况下检查资源是否被浏览器缓存?大多数问题和答案都是旧的,我相信现在情况发生了变化,并且有更好的方法。

【问题讨论】:

    标签: javascript caching fetch abort


    【解决方案1】:

    您可以利用fetch API 及其对应的AbortController 来实现此功能,但存在一定的误差(预计会出现误报)。

    它是这样的,fetch 所需的资源,附加了一个信号。在短时间内中止,例如。 4毫秒。如果 fetch 在短时间内返回,则它是绝对缓存的。如果提取被中止,它可能没有被缓存。这是一些代码:

          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
          }
    

    【讨论】:

    • 不下载资源
    • @JaromandaX 它正在快速中止,因此它没有被下载。
    • 你认为 setTimeout 会在 4 毫秒内触发吗?我认为 20 毫秒是最短可用时间(不过那是几年前的事了)
    • 一切都好 :p 我从这个答案中了解了 AbortController,所以 +1 :p 是的,我确实在你建议之后尝试了它,并考虑到使用 console.log 的延迟,4ms在 4 或 5 毫秒内触发超时!?
    【解决方案2】:

    不幸的是,目前仅适用于 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 看起来是这样,是的,这很不幸,因为 一些 跨站点资源没有 CORS 限制,仍然可以通过 JS 访问
    猜你喜欢
    • 2012-03-01
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 2014-08-07
    • 2013-09-29
    • 2022-01-15
    • 1970-01-01
    相关资源
    最近更新 更多