在"install"之前将状态信息传递给服务工作者

Bre*_*mir 17 javascript service-worker

背景

我是新来的服务人员,但在一个工作是打算成为"下线一"(确实,几乎是"脱机仅")(FWIW,目的是让图书馆的消费者提供代表表格JSON配置多线性文本,并获得一个应用程序,允许其用户通过段落/诗歌范围以高度可定制的方式浏览这些文本.)

其他项目是将库作为依赖项安装,然后通过我们的JavaScript API提供信息,例如JSON配置文件的路径,指示我们的应用程序将为其生成(离线)应用程序所使用的文件.

虽然我知道我们可以做以下任何事情:

  1. 要求用户提供硬编码路径,我们的服务工作者的install脚本可以使用waitUntil它自己的JSON请求来检索用户的必要文件
  2. 跳过install服务工作者对JSON文件的服务工作者的步骤,并依赖fetch事件来更新缓存,如果用户完成安装则提供后备显示,并在发生提取之前脱机.
  3. 将一些状态信息从我们的主脚本发布到服务器,服务工作者一旦注册,将在完成其install事件之前进行查询.

......但所有选择似乎都不太理想,因为:

  1. 我们图书馆的消费者可能更愿意为他们的JSON配置指定自己的位置.
  2. 鉴于JSON配置指定对显示其用户任何有用的关键文件,我宁愿不允许安装完成只是说如果用户无法保留,则必须返回联机以获取其余文件install事件发生后在线查看所有必需的提取.
  3. 除了希望避免更多访问服务器和额外代码之外,我更希望我们的代码能够如此离线,以便能够完全在纯静态文件服务器上工作.

题:

是否有某种方法可以在事件发生之前将消息或状态信息传递给服务工作者install,无论是作为服务工作者URL的查询字符串的一部分,还是通过消息传递事件?该消息的事件甚至可以在技术上到达后install事件之前开始,只要它可以发生waitUntilinstall完成.

我知道我可以自己测试一下,但是我想知道当关键应用程序文件必须像我们这样的库中动态获取时,最佳实践可能是什么.

我猜这indexedDB可能是唯一的选择(即,将配置信息或JSON配置的路径保存到indexedDB,注册服务工作者,并从install事件中检索indexedDB数据)?即使这样也不理想,因为我让用户为他们的存储定义一个命名空间,但是我也需要一种方法将它传递给worker,否则,源上的多个这样的应用程序可能会发生冲突.

Jef*_*ick 36

如果您发现它很有用,那么您可以在注册时将查询参数传递给服务工作者,如下所示:

// Inside your main page:
const pathToJson = '/path/to/file.json';
const swUrl = '/sw.js?pathToJson=' + encodeURIComponent(pathToJson);
navigator.serviceWorker.register(swUrl);

// Inside your sw.js:
self.addEventListener('install', event => {
  const pathToJson = new URL(location).searchParams.get('pathToJson');
  event.waitUntil(
    fetch(pathToJson)
      .then(response => response.json())
      .then(jsonData => /* Do something with jsonData */)
  );
});
Run Code Online (Sandbox Code Playgroud)

您还可能会发现在主页的上下文中将文件添加到缓存更容易,因为支持Cache Storage API的浏览器会通过它公开它fetch().但是install,在服务工作者的处理程序中预先缓存文件确实具有确保在服务工作者安装之前已成功缓存所有文件的优点.