【问题标题】:Force reload skipping Service Worker in JavaScript在 JavaScript 中强制重新加载跳过 Service Worker
【发布时间】:2017-10-23 04:19:33
【问题描述】:

Service Worker 可能会干扰刷新按钮(根据设计)。在桌面 Chrome 上,您可以按住 shift 并单击刷新按钮进行硬重新加载,忽略任何已安装的 ServiceWorker。

有没有办法强制重新加载而忽略 JavaScript 中的 SW?

(我想要这个,以便在 SW 开始出现异常行为时给移动用户一个按钮。手机没有 shift 键。)

【问题讨论】:

  • 我会告诉你我尝试过的一件事并没有达到我想要的效果。 window.location.reload(true)forcedRefresh 参数)通常应该等同于 shift-refresh,但在我的测试中,location.reload(true) 不会覆盖/忽略 SW;就软件而言,它与location.reload(false) 相同。 (这是 Chrome 中的错误吗??)
  • 如果你想删除所有缓存,你可以使用caches.delete developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/… 你可以通过你的js代码(按钮点击处理程序)与服务进行通信,服务工作者消息处理程序可以删除缓存(或只有一些)。服务人员完成后,重新加载页面:craig-russell.co.uk/2016/01/29/…

标签: javascript service-worker


【解决方案1】:

如果您在刷新前unregister Service Worker,则下一个页面加载将在没有 Service Worker 的情况下加载。

navigator.serviceWorker.getRegistration().then(function(reg) {
  if (reg) {
    reg.unregister().then(function() { window.location.reload(true); });
  } else {
     window.location.reload(true);
  }
});

【讨论】:

  • 我应该在哪里使用这个代码?在窗口的“beforeunload”事件处理程序中?每次重新加载时取消注册 SW 有什么影响?
  • @Arik 我从未打算在每次重新加载时运行此代码。我打算为用户提供一个屏幕上的“强制重新加载”按钮;代码将出现在按钮的单击处理程序中。我认为每次重新加载都强制刷新是没有意义的。那时,我认为您真的只想完全卸载服务人员,而无需更换。 (或者,如果您只想在刷新时激活更新的 Service Worker,那就是 different question entirely。)
  • Dan,我正在寻求解决另一个问题(在硬重新加载后无法让我的 SW 响应 fetch 事件),我错误地将您的答案与我的问题联系起来 :)跨度>
【解决方案2】:

这是我评论的一个例子:

页面脚本:

if('serviceWorker' in navigator){
  // Register service worker
  navigator.serviceWorker.register('/service-worker.js')
  .then(
    reg =>
      console.log("SW registration succeeded. Scope is "+reg.scope)
    ,err =>
      console.error("SW registration failed with error "+err)
  );
}

const send_message_to_sw = (msg) =>
  new Promise(
    (resolve, reject) => {
      // Create a Message Channel
      const msg_chan = new MessageChannel();

      // Handler for recieving message reply from service worker
      msg_chan.port1.onmessage = (event) => {
          if(event.data.error){
              reject(event.data.error);
          }else{
              resolve(event.data);
          }
      };

      // Send message to service worker along with port for reply
      navigator.serviceWorker.controller.postMessage(
        msg
        , [msg_chan.port2]
      );
  }
);

document.body.addEventListener(
  "click"
  ,()=>
    send_message_to_sw(
      {
        action:"delete"
        ,cache:/^v1$/
        ,url:/.*bundle.js$/
      }
    )
    .then(
      (msg)=>
        console.log("deleted:",msg)
    )
);

服务工作者:

console.log("SW Startup!");

// Install Service Worker
self.addEventListener(
  'install'
  ,(event)=>
    console.log('installed!')
);

// Service Worker Active
self.addEventListener(
  'activate'
  ,(event)=>
  console.log('activated!')
);
self.addEventListener(
  'fetch'
  ,(event) =>
    event.respondWith(
      caches.match(event.request)
      .then((resp) =>
          resp 
          || 
          fetch(event.request)
          .then(
            (response) =>
              caches.open('v1')
              .then(
                (cache) => {
                  cache.put(event.request, response.clone());
                  return response;
                }
              )  
          )
      )
    )
);
self.addEventListener(
  'message'
  ,(event) =>{
    const data = event.data || {};
    if(data.action === "delete"){
      var p = 
        caches.keys()
        .then(
          (keyList) =>
            keyList
            .filter(
              key=>data.cache.test(key)
            )
        )
      ;
      if(data.url === undefined) {
        p = p.then(
          (keyList) =>
            Promise.all(
              keyList
              .map((key) =>{
                caches.delete(key);
                return key;
              }
            )
          )
        )
      }else {
        p = p.then(
          (keyList) =>
            Promise.all(
              keyList
              .map((key) =>
                caches.open(key)
                .then(
                  (cache)=>
                    Promise.all([
                      cache
                      ,cache.keys()
                    ])
                )
                .then(
                  ([cache,items])=>
                    Promise.all(
                      items
                      .filter(item=>data.url.test(item.url))
                      .map(
                        item=>{
                          cache.delete(item);
                          return key + ":" + item.url
                        }
                      )
                    )
                )
            )
          )
        )        
      }
      return p.then(
        (keys)=>
          event.ports[0].postMessage(
            keys
            .reduce(
              (acc,item)=>acc.concat(item)
              ,[]
            )
          )
      );
    }
  }
);

【讨论】:

    猜你喜欢
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 2019-11-11
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多