javascript - 如何在 Service Worker 中编辑请求 url?

标签 javascript caching request service-worker progressive-web-apps

我正在为我的 pwa 使用缓存优先缓存策略,对于每个 GET 请求,我首先查看该请求是否存在于缓存中,如果存在,则返回它并更新缓存。
问题是用户可以在多个项目之间切换,所以当他们切换到另一个项目时,
他们第一次打开某个 url 时,他们会从以前的项目中获取内容(如果它存在于缓存中)。
我的解决方案是尝试在 service worker 中添加 GET parametar ?project=projectId(project=2 for example),这样每个项目都会在缓存中保存自己的请求版本。
我想将项目 ID 连接到 event.request.url,但我已经阅读了 here它是只读的。
这样做之后,希望我在缓存中会有这样的网址:

Instead of: https://stackoverflow.com/questions

I would have: https://stackoverflow.com/questions?project=1

And: https://stackoverflow.com/questions?project=2


所以我会从我正在参与的项目中得到问题,而不是仅仅从以前的项目中得到问题是/questions 已经保存在缓存中。
有没有办法在 Service Worker 中编辑请求 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 作为缓存键。通过 put() 写入缓存时,例如,您可以传入一个字符串,该字符串表示您想用作第一个参数的 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)

(我假设您有一些可靠的方法可以根据哪个客户端发出传入请求来确定 service worker 中正确的 someProjectId 值应该是什么。)

关于javascript - 如何在 Service Worker 中编辑请求 url?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59599539/

相关文章:

javascript - 禁用的属性不适用于 Xhtml

JavaScript : Split string using function and returning it

caching - 如何在Groovy和Grails中使用Spring AOP方面,特定的缓存示例

PHP 错误 一次插入导致两行 ANDROID

spring - 没有@RequestParam,参数绑定(bind)如何/为什么工作?

javascript - d3 带工具提示的条形图不起作用

javascript - 请求头字段 Cache-Control 不允许

javascript - 你如何使用 html5 localStorage 在 iphone Safari 上缓存 javascript?

Django CSRF 保护强制设置 "Vary: Cookie" header ,导致缓存效率低下