繁体   English   中英

如何在Firefox Service Worker中处理206个响应

[英]How to handle 206 responses in Firefox service workers

在测试服务人员的项目并使用Google提供的示例时:

/*
 Copyright 2016 Google Inc. All Rights Reserved.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

// Names of the two caches used in this version of the service worker.
// Change to v2, etc. when you update any of the local resources, which will
// in turn trigger the install event again.
const PRECACHE = 'precache-v1';
const RUNTIME = 'runtime';

// A list of local resources we always want to be cached.
const PRECACHE_URLS = [
  'index.html',
  './', // Alias for index.html
  'styles.css',
  '../../styles/main.css',
  'demo.js'
];

// The install handler takes care of precaching the resources we always need.
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(PRECACHE)
      .then(cache => cache.addAll(PRECACHE_URLS))
      .then(self.skipWaiting())
  );
});

// The activate handler takes care of cleaning up old caches.
self.addEventListener('activate', event => {
  const currentCaches = [PRECACHE, RUNTIME];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
    }).then(cachesToDelete => {
      return Promise.all(cachesToDelete.map(cacheToDelete => {
        return caches.delete(cacheToDelete);
      }));
    }).then(() => self.clients.claim())
  );
});

// The fetch handler serves responses for same-origin resources from a cache.
// If no response is found, it populates the runtime cache with the response
// from the network before returning it to the page.
self.addEventListener('fetch', event => {
  // Skip cross-origin requests, like those for Google Analytics.
  if (event.request.url.startsWith(self.location.origin)) {
    event.respondWith(
      caches.match(event.request).then(cachedResponse => {
        if (cachedResponse) {
          return cachedResponse;
        }

        return caches.open(RUNTIME).then(cache => {
          return fetch(event.request).then(response => {
            // Put a copy of the response in the runtime cache.
            return cache.put(event.request, response.clone()).then(() => {
              return response;
            });
          });
        });
      })
    );
  }
});

来源: https : //github.com/GoogleChrome/samples/blob/gh-pages/service-worker/basic/service-worker.js

我发现Firefox(与野生动物园和Chrome浏览器相反)会在event.waitUntil()以及event.respondWith()内引发错误,如果某些操作不适用于提取请求(即使它只是206部分内容响应):

服务工作者事件waitUntil()被传递了一个承诺,该承诺被'TypeError拒绝:尝试添加请求时,高速缓存获得状态为206的基本响应

这种行为会破坏安装程序。 如果我这样向安装程序添加.catch()

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(PRECACHE)
      .then(cache => cache.addAll(PRECACHE_URLS))
      .then(self.skipWaiting())
      .catch(function(err){
        console.log(err);
        self.skipWaiting();
      })
  );

});

我认为前206个将使预缓存停止(?)

另外在安装了sw之后,偶尔我会得到一个

服务工作者事件responseWith()已传递一个承诺,该承诺被'TypeError:尝试添加请求时,缓存状态为206的基本响应返回错误状态

即使没有发生,如果我尝试在安装/预缓存时尝试打开指向引发206错误的网址的链接,则会得到:

无法加载“ https://xxxx/yyyyy.mp3 ”。 一个ServiceWorker向FetchEvent.respondWith()传递了一个承诺,该承诺以“ TypeError:Cache尝试添加请求https://xxxx/yyyyy.mp3 ”时得到了状态为206的基本响应。

在浏览器内部,错误看起来像文件已损坏

如何正确处理此类错误? 像上面那样捕获并没有多大意义,因为它破坏了强制预缓存。 即使那是可以接受的,它似乎也会干扰从那时起发生的每个请求,并可能在以后引起麻烦。

我可以通过将return语句从cache.put()函数内部移出来解决一半的问题:

self.addEventListener('fetch', event => {
  // Skip cross-origin requests, like those for Google Analytics.
  if (event.request.url.startsWith(self.location.origin)) {
    event.respondWith(
      caches.match(event.request).then(cachedResponse => {
        if (cachedResponse) {
          return cachedResponse;
        }

        return caches.open(RUNTIME).then(cache => {
          return fetch(event.request).then(response => {
            // Put a copy of the response in the runtime cache.
            cache.put(event.request, response.clone()).then(() => {
              console.log("logged a file into RUNTIME:");
              console.log(response);
            });
            return response; // and return anyhow whatever came back
          });
        });
      })
    );
  }
});

这样,sw不会等待cache.put()成功,但是大多数时候它都会被缓存。

这解决了最紧迫的问题,但问题仍然存在

a)强制预缓存仍然被206个响应取消b)万一我想确保请求在运行时被缓存,我仍然需要做一些retry()函数或其他操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM