Eth*_*han 3 javascript runtime-error service-worker service-worker-events
我不断收到此错误:
未捕获(承诺)DOMException:无法对“ FetchEvent”执行“ respondWith”:事件已得到响应。
我知道,如果异步操作在fetch函数中进行,服务人员会自动做出响应,但是我无法完全确定在此代码中哪位是罪魁祸首:
importScripts('cache-polyfill.js');
self.addEventListener('fetch', function(event) {
var location = self.location;
console.log("loc", location)
self.clients.matchAll({includeUncontrolled: true}).then(clients => {
for (const client of clients) {
const clientUrl = new URL(client.url);
console.log("SO", clientUrl);
if(clientUrl.searchParams.get("url") != undefined && clientUrl.searchParams.get("url") != '') {
location = client.url;
}
}
console.log("loc2", location)
var url = new URL(location).searchParams.get('url').toString();
console.log(event.request.hostname);
var toRequest = event.request.url;
console.log("Req:", toRequest);
var parser2 = new URL(location);
var parser3 = new URL(url);
var parser = new URL(toRequest);
console.log("if",parser.host,parser2.host,parser.host === parser2.host);
if(parser.host === parser2.host) {
toRequest = toRequest.replace('https://booligoosh.github.io',parser3.protocol + '//' + parser3.host);
console.log("ifdone",toRequest);
}
console.log("toRequest:",toRequest);
event.respondWith(httpGet('https://cors-anywhere.herokuapp.com/' + toRequest));
});
});
function httpGet(theUrl) {
/*var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
xmlHttp.send( null );
return xmlHttp.responseText;*/
return(fetch(theUrl));
}
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激。
问题在于您的调用event.respondWith()位于顶级Promise的.then()子句中,这意味着它将在顶级Promise解析后异步执行。为了获得您期望的行为,event.respondWith()需要作为fetch事件处理程序执行的一部分同步执行。
您的诺言中的逻辑有点难以遵循,因此我不确定您要实现的目标,但总的来说,您可以遵循以下模式:
self.addEventListerner('fetch', event => {
// Perform any synchronous checks to see whether you want to respond.
// E.g., check the value of event.request.url.
if (event.request.url.includes('something')) {
const promiseChain = doSomethingAsync()
.then(() => doSomethingAsyncThatReturnsAURL())
.then(someUrl => fetch(someUrl));
// Instead of fetch(), you could have called caches.match(),
// or anything else that returns a promise for a Response.
// Synchronously call event.respondWith(), passing in the
// async promise chain.
event.respondWith(promiseChain);
}
});
Run Code Online (Sandbox Code Playgroud)
那是一般的想法。(如果最终用async/ 替换promise,则代码看起来更加简洁await。)
我在尝试在 fetch 处理程序中使用 async/await 时也偶然发现了这个错误。正如杰夫在他的回答中提到的,event.respondWith必须同步调用,参数可以是任何返回解析为响应的承诺的东西。由于 async 函数确实会返回一个 promise,因此您所要做的就是将 fetch 逻辑包装在一个 async 函数中,该函数在某个时候返回一个响应对象并event.respondWith使用该处理程序进行调用。
async function handleRequest(request) {
const response = await fetch(request)
// ...perform additional logic
return response
}
self.addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request));
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1350 次 |
| 最近记录: |