0

这是我第一次尝试服务人员,我确信我在做一些愚蠢的事情。服务人员缓存文件但不加载离线

  • 我有一个服务人员为我正在处理的WordPress主题设置。它位于/public_html/wp-content/themes/framework/assets/scripts/service-worker.js
  • 我已通过.htaccess文件设置标头Servie-Worker-Allowed: "/"
  • 我使用sw-toolbox使事情变得更容易。我的脚本在下面。

脚本:

toolbox.precache(["/", "../media/logo.svg", "../media/spritesheet.svg", "../scripts/modern.js", "../styles/modern.css"]); 
toolbox.router.get("../media/*", toolbox.cacheFirst); 
toolbox.router.get("/wp-content/uploads/*", toolbox.cacheFirst); 
toolbox.router.get("/*", toolbox.networkFirst, {NetworkTimeoutSeconds: 5}); 

服务工作者正确地注册,并不会引发任何错误。所有设置为预缓存的文件都会在Chrome的开发人员工具中正确显示在Cache > Cache Storage之下。由于某些原因,这些缓存的文件在脱机时不会处于服务状态。

我知道服务人员的服务范围有问题,但Service-Worker-Allowed标题应该正确。鉴于这些文件确实在缓存中显示没有问题,我认为这一切都正常工作。

我错过了什么?

注:我想保持service-worker.js,我缓存文件,他们是和相对路径;将它们移动到根目录或给它们绝对路径会产生问题,因为这个WordPress主题被重新用于构建,并且每次都更改它的名称,使绝对路径变得很痛苦。我测试了重写到.htaccess,这确实有效,但它有它自己的问题。我不明白为什么这会工作,但我目前尝试不会。

+0

如何测试脱机功能?如果你没有在服务工作者的'activate'处理程序中调用'clients.claim()',那么你应该知道服务工作人员不会控制当前页面,你需要导航然后返回到服务工作人员控制:https://stackoverflow.com/a/41066148/385997 –

+0

@JeffPosnick谢谢,我会看看如果我能弄清楚。 – JacobTheDev

回答

2

我想我正在讨论这个错误。似乎没有必要手动指定缓存我的主题资产,只要我已启用缓存一般。为此,我已经建立了一个重写规则,以便service-worker.js位于根(即https://www.example.com/service-worker.js),从而给出正确的范围。这使我的项目脱机工作。代码如下。

((global) => { 
    // disable the service worker for post previews 
    global.addEventListener("fetch", (event) => { 
     if (event.request.url.match(/preview=true/)) { 
      return; 
     } 
    }); 

    // ensure the service worker takes over as soon as possible 
    global.addEventListener("install", event => event.waitUntil(global.skipWaiting())); 
    global.addEventListener("activate", event => event.waitUntil(global.clients.claim())); 

    // set up the cache 
    global.toolbox.precache(["/", "/offline/"]); 
    global.toolbox.router.get("/wp-content/uploads/*", toolbox.cacheFirst); 
    global.toolbox.router.get("/*", toolbox.networkFirst, {NetworkTimeoutSeconds: 5}); 

    // redirect offline queries to offline page 
    self.toolbox.router.get("/(.*)", function (req, vals, opts) { 
     return toolbox.networkFirst(req, vals, opts).catch((error) => { 
      if (req.method === "GET" && req.headers.get("accept").includes("text/html")) { 
       return toolbox.cacheOnly(new Request("/offline/"), vals, opts); 
      } 

      throw error; 
     }); 
    }); 
})(self);