javascript – Service Worker’fetch’事件当前正在提供的页面的URL

如何获取服务工作者的’fetch’事件所服务的页面的完整URL?

“self.location”属性似乎只引用站点的根URL.例如,如果页面https://example.com/folder/pagename.html正在执行服务工作者正在拦截的提取,则服务工作者的“self.location”属性返回“https://example.com”.

event.currentTarget.location和event.explicitOriginalTarget.location,event.originalTarget和event.target都返回服务工作者.js文件的URL.

如何获取触发fetch事件的页面的完整URL?

解决方法:

您有两种常规方法,具体取决于您希望获得的方式:

使用“Referer”标题信息

如果请求是针对子资源并包含Referer标头,那么该标头的值很可能是发出请求的页面的URL. (有一些警告;请阅读this background info以深入研究.)

在获取处理程序中,您可以使用以下内容读取该标头的值:

self.addEventListener('fetch', event => {
  const clientUrl = event.request.referrer;
  if (clientUrl) {
    // Do something...
  } 
});

使用clientId值

另一种方法是使用(可能)在FetchEvent上公开的clientId值,然后使用clients.get(id)或循环遍历clients.matchAll()的输出以查找匹配的WindowClient.然后,您可以读取该WindowClient的url属性.

这种方法的一个警告是,查找WindowClient的方法都是异步的,并返回promise,所以如果你以某种方式使用客户端窗口的URL来确定是否要调用event.respondWith(),你运气不好(当首次调用FetchEvent处理程序时,需要同步做出决定).

为了使这种方法起作用,需要支持不同的东西组合,我不确定哪些浏览器目前支持我提到的所有内容.我知道Chrome 67确实存在(因为我刚刚在那里测试过),但是如果这个功能对你很重要,你应该在其他浏览器中查看.

self.addEventListener('fetch', async event => {
  const clientId = event.clientId;
  if (clientId) {
    if ('get' in clients) {
      const client = await clients.get(clientId);
      const clientUrl = client.url;
      // Do something...
    } else {
      const allClients = await clients.matchAll({type: 'window'});
      const filtered = allClients.filter(client => client.id === clientId);
      if (filtered.length > 0) {
        const clientUrl = filtered[0].url;
        // Do something...
      }
    }
  }
});
上一篇:Java 网络编程 字符流的发送与接收 自定义数据边界


下一篇:javascript – 检测服务工作者中脱机状态的最佳实践