如何挂钩到不使用服务工作者的fetch方法?
我知道我可以使用服务工作者来做,但还有其他方法吗?不使用服务工作者?
重要:
fetch
的供应商模块,我也想覆盖那个addEventListener('fetch', event => {
// Let the browser do its default thing
// for non-GET requests.
if (event.request.method != 'GET') return;
// Prevent the default, and handle the request ourselves.
event.respondWith(async function() {
// Try to get the response from a cache.
const cache = await caches.open('dynamic-v1');
const cachedResponse = await cache.match(event.request);
if (cachedResponse) {
// If we found a match in the cache, return it, but also
// update the entry in the cache in the background.
event.waitUntil(cache.add(event.request));
return cachedResponse;
}
// If we didn't find a match in the cache, use the network.
return fetch(event.request);
}());
});
我想到的一件事是包装window.fetch
方法,但我不喜欢这个解决方案。
window.fetch = async function(requestUrl) {
// Try to get the response from a cache.
const cache = await caches.open('dynamic-v1');
const url = new URL(requestUrl);
const cachedResponse = await cache.match(url.pathname);
if (cachedResponse) {
return cachedResponse;
}
return fetch(requestUrl);
}
Ofc这个例子只是理论上的,所以有什么想法吗?
答案 0 :(得分:1)
这不是这个问题的真正答案,但无论如何我会在这里发布,因为它可能对某人有帮助。
所以我需要做的就是在客户端处理一些东西(不在sw中),我通过使用MessageChannel
来实现它,让sw和客户端进行双向通信。
你可以从这个谷歌的例子中得到基本的想法: https://googlechrome.github.io/samples/service-worker/post-message/
最重要的部分是将工作委托给客户,让它在另一个端口上做出响应,将整个过程转变为这样的承诺:
// This wraps the message posting/response in a promise, which will resolve if the response doesn't
// contain an error, and reject with the error if it does. If you'd prefer, it's possible to call
// controller.postMessage() and set up the onmessage handler independently of a promise, but this is
// a convenient wrapper.
return await new Promise((resolve, reject) => {
let messageChannel = new MessageChannel();
messageChannel.port1.onmessage = function (event) {
if (event.data && event.data.error) {
reject(event.data.error);
} else {
resolve(event.data);
}
};
// This sends the message data as well as transferring messageChannel.port2 to the client.
// The client can then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
// See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
client.postMessage(message, [messageChannel.port2]);
// Set up the timeout
setTimeout(() => {
messageChannel.port1.close();
messageChannel.port2.close();
reject('Promise timed out after ' + this.timeoutAfter + ' ms');
}, this.timeoutAfter);
});
如果您希望查看我的用例,可以使用here MessageClient来完成工作{/ 3}}
随便提出问题,将很乐意回答