跨域ServiceWorker负载均衡

问题描述 投票:0回答:1

我正在尝试用ServiceWorker API实现类似跨域负载均衡的东西。

我的概念是。

  1. 在安装后,每当fetch事件发生时,我都会尝试访问主域(https:/example.com)
  2. 如果成功的话,我应该把这个返回给用户,并注明 "喜欢"。event.respondWith(__response);
  3. 如果失败(超时或任何其他异常),我向其他服务器发出CORS请求(https:/balancer.com),它返回其他可访问域(https:/mirror1.example.com。),浏览器被重定向。

而我卡在重定向步骤(((所以我现在的代码是这样的

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();
                    }
                }
            });
    });
};
javascript service-worker
1个回答
0
投票

获取一个引用到一个 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.
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.