我正在尝试使用ServiceWorker API来实现跨域负载平衡之类的smth。
我的概念是:
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();
}
}
});
});
};
答案 0 :(得分:0)
获取对WindowClient
的引用并从fetch
处理程序内部强行更改其URL是重定向的正确方法。
相反,在fetch
处理程序内部,您可以使用Response.redirect()
创建的重定向响应进行响应。从浏览器的角度来看,这将与可能源自服务器的任何其他重定向一样对待。
要注意的一件事是,如果最初通过相同来源的URL请求子资源而导致重定向到跨来源响应,则可能会遇到一些问题。如果您最初的请求是针对跨域URL,并且您的潜在重定向也针对跨域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.
}
});