在缓存 API 中,使用 caches.match(event.request) 和 caches.match(event.request.url) 有什么区别

in the Cache API , what is the difference between using caches.match(event.request) and caches.match(event.request.url)

我正在使用 services worker,我有以下代码

  self.addEventListener('fetch', function (event) {
    const url = new URL(event.request.url)

    if (event.request.mode == "navigate") {
        const fetchData = fetch(event.request).catch(function () {
            //console.log("errr")
            return caches.match("/core/index.php/offline_controlador/index")
        });
        event.respondWith(fetchData)
        return;
    }

    event.respondWith(
        caches.match(event.request).then(function (response) {
            return response || fetch(event.request);
        })
    );
 });

当我试图从缓存中获取这些文件时,它不起作用,但是当我将代码更改为

event.respondWith(
        caches.match(event.request.url).then(function(response) {
          return response || fetch(event.request);
        })
    );

而不是

event.respondWith(
            caches.match(event.request).then(function(response) {
              return response || fetch(event.request);
            })
        );

效果完美

缓存存储 API 规范的相关部分是 5.4.2。 (尽管这适用于 Cache 对象的 matchAll() 方法,但当您执行 caches.match().

时,最终会调用 "under the hood"

与您的问题特别相关的是第 2 步:

If the optional argument request is not omitted, then:

  • If request is a Request object, then:

    • Set r to request’s request.

    • If r’s method is not GET and options.ignoreMethod is false, return a promise resolved with an empty array.

  • Else if request is a string, then:

    • Set r to the associated request of the result of invoking the initial value of Request as constructor with request as its argument. If this throws an exception, return a promise rejected with that exception.

总而言之,最大的区别在于,如果 Request 具有 method,则将 Request 对象作为第一个参数传递可能会导致 match() 失败'GET' 以外的东西。也许这就是您遇到的问题。

除此之外,这两种方法应该基本相同,尽管传入 Request 效率稍微高一些,因为浏览器不必隐式创建基于 Request 的对象在字符串上。