Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/437.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在service worker中编辑请求url?_Javascript_Caching_Request_Service Worker_Progressive Web Apps - Fatal编程技术网

Javascript 如何在service worker中编辑请求url?

Javascript 如何在service worker中编辑请求url?,javascript,caching,request,service-worker,progressive-web-apps,Javascript,Caching,Request,Service Worker,Progressive Web Apps,我在pwa中使用缓存优先缓存策略,对于每个GET请求,我首先查看该请求是否存在于缓存中,如果存在,则返回该请求并更新缓存 问题是用户可以在多个项目之间切换,所以当他们切换到另一个项目时, 当他们第一次打开某个url时,如果缓存中存在上一个项目,他们就会从中获取该项目的内容 我的解决方案是尝试在服务工作者中添加GET-parametar?project=projectd(例如,project=2),这样每个项目都会在缓存中保存自己的请求版本。 我想将项目id关联到event.request.url

我在pwa中使用缓存优先缓存策略,对于每个GET请求,我首先查看该请求是否存在于缓存中,如果存在,则返回该请求并更新缓存

问题是用户可以在多个项目之间切换,所以当他们切换到另一个项目时, 当他们第一次打开某个url时,如果缓存中存在上一个项目,他们就会从中获取该项目的内容

我的解决方案是尝试在服务工作者中添加GET-parametar?project=projectd(例如,project=2),这样每个项目都会在缓存中保存自己的请求版本。 我想将项目id关联到event.request.url,但我已经读到它是只读的

这样做之后,我希望缓存中的URL如下所示:

而不是:

我会:

以及:

因此,我会从我参与的项目中获取问题,而不仅仅是从先前的项目中获取问题,因为问题已经保存在缓存中

有没有办法在服务工作者中编辑请求url

我的服务人员代码:

self.addEventListener('fetch', function(event) {
  
  const url = new URL(event.request.clone().url);
  if (event.request.clone().method === 'POST') {
      // update project id in service worker when it's changed
      if(url.pathname.indexOf('/project/') != -1 ) {
            // update user data on project switch
            let splitUrl = url.pathname.split('/');
            if (splitUrl[2] && !isNaN(splitUrl[2])) {
                console.log( user );
                setTimeout(function() {
                  fetchUserData();
                  console.log( user );
                }, 1000);
            }
       }  
       // do other unrelated stuff to post requests
       .....
  } else { // HANDLE GET REQUESTS
      // ideally,here I would be able to do something like this:
      if(user.project_id !== 'undefined') {
          event.request.url = event.request.url + '?project=' + user.project_id;
      }

      event.respondWith(async function () {
        const cache = await caches.open('CACHE_NAME')

        const cachedResponsePromise = await cache.match(event.request.clone())
        const networkResponsePromise = fetch(event.request.clone())
        if (event.request.clone().url.startsWith(self.location.origin)) {
          event.waitUntil(async function () {
            const networkResponse = await networkResponsePromise.catch(function(err) {
              console.log( 'CACHE' );
              // return caches.match(event.request);
              return caches.match(event.request).then(function(result) {
                  // If no match, result will be undefined
                  if (result) {
                       return result;
                  } else {
                       return caches.open('static_cache')
                         .then((cache) => {
                             return caches.match('/offline.html');
                       });
                  }
             });
            });
            await cache.put(event.request.clone(), networkResponse.clone())
          }())
        }
       
        // news and single photos should be network first       
        if (url.pathname.indexOf("news") > -1 || url.pathname.indexOf("/photos/") > -1) {
            return networkResponsePromise || cachedResponsePromise;  
        }
        return cachedResponsePromise || networkResponsePromise;
      }())
      
  }
});

在读取/写入缓存存储API时,可以使用任何URL作为缓存密钥。例如,通过写入缓存时,可以传入表示要用作第一个参数的URL的字符串:

// You're currently using:
await cache.put(event.request.clone(), networkResponse.clone())

// Instead, you could use:
await cache.put(event.request.url + '?project=' + someProjectId, networkResponse.clone())
但我认为更好的方法是为每个项目使用不同的缓存名称,这样在每个不同名称的缓存中,就不必担心修改缓存键以避免冲突

// You're currently using:
const cache = await caches.open('CACHE_NAME')

// Instead, you could use:
const cache = await caches.open('CACHE_NAME' + someProjectId)
(我假设您有一些可靠的方法,可以根据发出传入请求的客户机,计算出服务工作者内部正确的someProjectId值。)