我正在尝试用ServiceWorker API实现类似跨域负载均衡的东西。
我的概念是。
event.respondWith(__response)
;而我卡在重定向步骤(((所以我现在的代码是这样的
self.oninstall = function (event) {
event.waitUntil(self.skipWaiting());
};
self.onactivate = function (event) {
event.waitUntil(self.clients.claim());
};
self.initialUrl = false;
self.onfetch = async function (event) {
if (!self.initialUrl)
self.initialUrl = event.request.url;
if (self.initialUrl) {
event.respondWith(self.tryAccess(event))
} else {
event.respondWith(fetch(event.request));
}
};
self.tryAccess = async (event) => {
return new Promise(async (resolve, reject) => {
self.clients
.matchAll({type: 'window'})
.then(async (clients) => {
for (var i in clients) {
var _c = clients[0];
if (_c.url === event.request.url) {
try {
let __tryResponse = await fetch(event.request);
resolve(__tryResponse);
return;
} catch (e) {
let __json = await (await fetch("https://balancer.com/")).json();
return _c.navigate(__json.path).then(client => client.focus());
}
} else {
resolve();
}
}
});
});
};
获取一个引用到一个 WindowClient
并强行将其URL从内部的 fetch
handler不是重定向的正确方式。
相反,在你的 fetch
处理程序,您可以使用由 Response.redirect()
. 从浏览器的角度来看,这将被视为像任何其他可能来自服务器的重定向一样。
需要注意的是,如果你最初通过同源URL请求一个子资源,结果重定向到一个跨源响应,你可能会遇到一些问题。如果你最初的请求是为了跨源网址,而你潜在的重定向也是为了跨源网址,我想你会没事的。
self.addEventListener('fetch', (event) => {
const fetchWithRedirection = async () => {
try {
// Use fetch(), caches.match(), etc. to get a response.
const response = await ...;
// Optional: also check response.ok, but that
// will always be false for opaque responses.
if (response) {
return response;
}
// If we don't have a valid response, trigger catch().
throw new Error('Unable to get a response.');
} catch (error) {
// Use whatever logic you need to get the redirection URL.
const redirectionURL = await ...;
if (redirectionURL) {
// HTTP 302 indicates a temporary redirect.
return Response.redirect(redirectionURL, 302);
}
// If we get to this point, redirection isn't possible,
// so just trigger a NetworkError.
throw error;
}
};
// You will probably want to wrap this in an if() to ensure
// that it's a request that you want to handle with redirection.
if (/* some routing criteria */) {
event.respondWith(fetchWithRedirection());
} else {
// Optionally use different response generation logic.
// Or just don't call event.respondWith(), and the
// browser will proceed without service worker involvement.
}
});