微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Service Worker 中通过网络发送 URL 之前从 URL 中删除搜索参数?

如何解决如何在 Service Worker 中通过网络发送 URL 之前从 URL 中删除搜索参数?

我正在构建一个应用程序,它将利用 ServiceWorker 和索引数据库来缓存数据并允许用户离线工作。该站点使用两个页面:index.html 和activity.html。主页将显示活动列表。选择其中一个活动时,它将其重定向到Activity.html并将所选活动传递为URL参数。该页面加载了从索引数据库提取的特定活动的数据。

这个想法是用户在早上登录主页,然后可以离线访问他们的每个活动,而无需互联网连接。如果用户在线时打开每个活动,然后离线,则此方法有效。但是,如果他们只访问主页,然后离线,然后单击某个活动,则会收到此错误

加载失败 ‘https://[site]/activity.html?activityid=35956087’。 ServiceWorker 向 FetchEvent.respondWith() 传递了一个承诺,即 尝试获取时因“类型错误:网络错误”而被拒绝 资源。'.

我猜我没有正确缓存某些东西,但我不知道为什么。这是 serviceworker.js:

var urlsToCache = [
    '/[webapp]/activity.html',//Web app title removed for posting online
    '/[webapp]/index.html',...
];

self.addEventListener('install',function(event) {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
       console.log('Service Workers opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});


self.addEventListener('activate',function(event) {
  event.waitUntil(function(){
    
  }
  );
});

self.addEventListener('fetch',function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }

        return fetch(event.request).then(
          function(response) {
            // Check if we received a valid response
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }

            // copied from another source:
        // IMPORTANT: Clone the response. A response is a stream
            // and because we want the browser to consume the response
            // as well as the cache consuming the response,we need
            // to clone it so we have two streams.
            var responsetoCache = response.clone();

            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request,responsetoCache);
              });

            return response;
          }
        );
      })
    );
});

编辑:我已经确定问题是由 URL 参数引起的(IMO,这完全是荒谬的)。从请求中去除 URL 参数的正确方法是什么?

解决方法

为了更改 Request 的 URL,您别无选择,只能通过从当前属性中提取属性来创建一个新的 URL,因为以下三个原因:

  • Request 对象在设计上是不可变的
  • Request 构造函数采用 Request 作为第一个参数,但不采用 URL 作为第二个参数
  • Request.clone() 方法只是创建 Request 的精确副本并且不接受任何参数

这是一个 stripParameters 函数的可能通用实现,该函数克隆 Request,同时从 URL 中剥离参数并保留其他属性(如 methodheaders 和其他):

const req = new Request("https://www.stackoverflow.com/path?param=foo",{
  method: "POST",headers: { "Authorization": "token" }
});

function stripParameters(request) {
  const keys = Object.entries(
    Object.getOwnPropertyDescriptors(Request.prototype)
  )
    .filter(([,value]) => !value.writable)
    .map(([key]) => key);
  const extractedProperties = keys.reduce(
    (acc,cur) => ({ ...acc,[cur]: request[cur] }),{}
  );
  const url = new URL(extractedProperties.url);
  const strippedUrl = url.href.replace(url.search,"");
  return new Request(strippedUrl,extractedProperties);
}

console.log(stripParameters(req));

,

虽然 Guerric P 克隆响应的选项可能会起作用,但忽略 URL 参数的最简单选项(我后来发现并成功实现)是使用 cache.match() 函数的“ignoreSearch”参数。

替换这个:

  event.respondWith(caches.match(event.request)

有了这个:

event.respondWith(caches.match(event.request,{'ignoreSearch' : true})

根据文档:

ignoreSearch:一个布尔值,指定是否忽略查询 URL 中的字符串。例如,如果设置为 true ?value=bar 部分 http://example.com/?value=bar 在执行匹配时将被忽略。它 默认为 false。

此处的完整文档:https://developer.mozilla.org/en-US/docs/Web/API/Cache/match

如果您需要以任何方式实际更改请求,例如修改 URL 参数而不是在 fetch 请求中忽略它们,您将需要使用 Guerric P 的克隆请求选项。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。