当前位置: 首页 > 知识库问答 >
问题:

用fetch事件替换service worker中的资产

弓玉书
2023-03-14

我正试图与我的服务人员热切换主题样式表。

我为Jekyll创建了一个主题(与GitHub页面一起使用),并希望能够在黑暗主题和光明主题之间进行替换(“关闭灯光”)并使其保持一致。

现在,这是通过将状态保存到localstore并根据此替换主题link元素来实现的。

问题是,检查发生在原始的白色主题被提取之后,所以即使localstore设置了黑色主题,用户也会看到白色主题的闪光

以下是它目前的行为(按钮在右上方):https://thatkookooguy.github.io/postmortem-demo/postmortem/002

更改主题后,请尝试导航到其他页面。页面加载白色主题,然后更改为黑色主题

我想我可以通过在服务工作者中切换脚本来解决这个问题,因为我可以将addEventListener添加到finch事件中,并在promise链中用另一个提取替换它。

但代码似乎不起作用。如果我在事件回调中添加调试点,它永远不会被触发(不在资产上,也不在实际的页面获取上)

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel='stylesheet prefetch' href='//fonts.googleapis.com/css?family=Fredoka+One|Righteous'>
  <!-- THIS SHOULD BE INTERCEPTED BY THE SERVICE WORKER -->
  <link id="bulma-theme" rel="stylesheet prefetch" href="//unpkg.com/bulmaswatch/default/bulmaswatch.min.css">
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
  <link rel="stylesheet" type="text/css" href="{{ site.baseurl }}/assets/style.css" />
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker
        .register('{{ site.baseurl }}/assets/sw.js')
        .then(function() {
          console.log("Service Worker Registered");
        });
    }
  </script>
</head>
importScripts('localforage.min.js');

// remember the theme
this.onmessage = function(msg) {
  if (!msg.data.theme) {
    return;
  }

  localforage.setItem('theme', msg.data.theme);
}

// replace link fetching with correct theme
this.addEventListener('fetch', function(event) {
  console.log(event.request.url);

  if (event.request.url.contains('/bulmaswatch/')) {
    return localforage.getItem('theme')
      .then(function(theme) {
        if (theme === 'kb-dark-theme') {

          let darkThemeRequest = new Request(request.url.replace('bulmaswatch/default/', 'bulmaswatch/superhero/'), {
            method: request.method,
            headers: request.headers,
            mode: 'same-origin',
            credentials: request.credentials,
            redirect: 'manual'
          });

          return fetch(darkThemeRequest);
        }

        return fetch(event.request);
      })
  }
});

// Log SW installation
this.addEventListener('install', function(event) {
  console.log('[SW]: installing....');
});

// Log SW activation
this.addEventListener('activate', function activator(event) {
  console.log('[SW]: activate!');
});

当在chrome中调试时(还有chrome canary,因为我听说那里有更好的服务人员调试支持),甚至从未调用fetch上的回调。没有记录任何请求。

我确实看到服务工作者在chrome的开发工具中注册并活动。我看到其他事件记录在控制台上。

此外,当调试并在脚本的开头放置断点时,看起来bulmaswatch.min.css已经被读取。

知道我错过了什么吗?:-)

谢啦

共有1个答案

孙才捷
2023-03-14

根本问题与服务人员的范围有关。

当我访问https://thatkookooguy.github.io/postmortem-demo/postmortem/002并在应用程序中查看

如果将sw移动。js文件从/assets/子目录中取出,并进入站点的顶级目录(即/postmortem demo/),然后切换注册码以反映这一点,然后您的服务人员应该能够控制您的客户端页面:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/postmortem-demo/sw.js');
}

(这意味着在本地开发时,还应该为Web应用提供URL前缀/postmortem-demo/以匹配该前缀。)

以下资源提供了有关服务人员范围的详细信息:

  • https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#scope_and_control
 类似资料:
  • 问题内容: 由于DOM突变被w3c标记为已弃用,因此存在一种(快速)替代方法来检测属性修改在DOM中? 问题答案: 据我所知,还没有其他选择,因此您只能使用Firefox和Opera支持的方法。在IE中,您有活动,但是无法在Chrome / Safari中获得类似的功能。根据您要完成的任务和目标浏览器,您可以做很多事情: 为要监视的属性定义获取器和设置器 重写方法一样,… 我本人一直在从事跨浏览器

  • 问题内容: 说我有一个字符串,。 我想,以取代与和具有一举。 因此,最后,该字符串应为and not or并且不使用多于一行。这可行吗? 问题答案: 当您需要交换变量时,例如 x 和 y ,常见的模式是引入一个临时变量 t 来帮助进行交换: 。 字符串也可以使用相同的模式: 这项技术不是新技术。PEP 378中将其描述为一种在美国和欧洲风格的小数点分隔符和数千个分隔符之间进行转换的方法(例如fro

  • 问题内容: 在是否有可能使用isomporphic取的,而不是Rx.DOM.ajax? 问题答案: (注意:来自RxJS v4 ,并且不能与需要RxJS v5的版本 一起使用。v5中的等效项是或) 确实可以使用以及其他任何AJAX API。虽然有些适应比其他容易! 该API返回a ,RxJS v5对此具有 内置支持 。该预期可观察到的最能消耗运营商承诺按原样(如,等)。但是通常您需要在将Rx运算符

  • 在我的ServiceWorker中,我有以下代码: 如果单击主页中的按钮,则会向工作人员发送消息。这很好,我看到消息:和记录在控制台中。自身。setTimeout调用不会引发错误,但从不调用send_alert。 根据https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope实现窗口计时器,它实现设置超时

  • 问题内容: 我有一个名为FormatString.java的文本文件。它包含一些单词。在所有这些单词中,我想将单词oldstring替换为newstring,并将最终结果重命名为t.txt。我已经编写了代码。从技术上讲,它应该起作用。问题是我不知道在哪里保存FormatString.java文件。我是否将其保存在保存了ReplacingText程序的同一类文件夹中,还是将其保存在其他地方。我转到命

  • 问题内容: 我使用md5 grunt任务生成MD5文件名。现在,我想在任务的回调中使用新文件名重命名HTML文件中的源。我想知道什么是最简单的方法。 问题答案: 您可以使用简单的正则表达式: 所以…