Asp.net mvc 服务工作者-具有动态参数的缓存页

Asp.net mvc 服务工作者-具有动态参数的缓存页,asp.net-mvc,service-worker,workbox,Asp.net Mvc,Service Worker,Workbox,我通过Workbox使用service worker来缓存.NET MVC索引视图的结果,该视图是一个简单的URL,例如。请注意,缓存由页面本身以及在设计/编译时未知的网格中呈现的JSON格式的数据组成,即JSON数据在运行时通过从数据库检索。这一切都很好——离线时缓存 网格中的每一行都包含一个按钮,单击该按钮将转到另一个MVC视图。我还想缓存这些页面,比如在初始网格中出现的前2个页面。因此,我不知道前两个页面的URL,因为它们包含从数据库检索到的参数,这是它们的一个示例:- …从数据库检索“3

我通过Workbox使用service worker来缓存.NET MVC索引视图的结果,该视图是一个简单的URL,例如。请注意,缓存由页面本身以及在设计/编译时未知的网格中呈现的JSON格式的数据组成,即JSON数据在运行时通过从数据库检索。这一切都很好——离线时缓存

网格中的每一行都包含一个按钮,单击该按钮将转到另一个MVC视图。我还想缓存这些页面,比如在初始网格中出现的前2个页面。因此,我不知道前两个页面的URL,因为它们包含从数据库检索到的参数,这是它们的一个示例:-

…从数据库检索“33”部分,因此无法提前知道

下面的服务工作者遍历从初始索引页缓存的JSON数据,获取每行的Id字段,并将其后缀添加到URL的末尾,然后我尝试“获取”页面,然后缓存它

    cache.match('https://mysite.local/MyWebsite/Product/LoadData')
        .then(function(matchedResponse) {
            return matchedResponse.json();
        })
        .then(function (json) {
            for (var i = 0; i < json.data.length; i++) {
                const API_FurtherInformation_URL = 'https://mysite.local/MyWebsite/Product/FurtherInformation/' + json.data[i].Id + '/0';

                const apiLoadDataCallHandler = workbox.strategies.networkFirst({
                    cacheName: 'my-cache'
                });

                workbox.routing.registerRoute(
                    API_FurtherInformation_URL ,
                    apiLoadDataCallHandler 
                );

                self.addEventListener('install', event => {
                    event.waitUntil(
                      caches.open('my-cache')
                        .then(cache => cache.add(API_FurtherInformation_URL))
                    );
                });

                self.addEventListener('fetch', event => {
                    if (event.request.mode === 'navigate') {
                        event.respondWith(
                          fetch(event.request).catch(() => caches.match(API_FurtherInformation_URL))
                        );
                    }
                });
            }
        });
});
但是,代码中的“安装”和“获取”事件逻辑都会收到警告消息:-

“安装”事件的事件处理程序必须添加到辅助脚本的初始评估中

“fetch”事件的事件处理程序必须添加到辅助脚本的初始评估中

…并且该页未被缓存

你知道我能做些什么吗?这个场景适合吗?

错误消息的意思是: 在最初执行SW脚本之后,不能添加self.addEventListener'fetch'或self.addEventListener'install',换句话说,不能将它们添加到循环中。在第一次执行时,必须在脚本的顶层添加这些事件侦听器

您还应该注意,您正在添加的那些事件侦听器是事件的事件侦听器。它们不是像你说的那样用来缓存东西的命令

我想你可以这样做:

caches.open('my-cache')
  .then(cache => cache.add(API_FurtherInformation_URL))
在循环内部,请注意缓存可能已经打开,至少在外部作用域中有一个具有该名称的变量。您不需要添加事件侦听器

总而言之,我认为您不应该真正实现这样的功能。它使您的服务工作者代码与API端点等非常耦合。例如,我建议您重构代码,使其工作方式如下:

服务工作者侦听来自页面的消息 这些消息包括应该缓存的URL 收到消息后,软件会立即缓存URL 现在,当JS在页面上执行并为用户呈现url时,它可以向SW发送一条消息,并告诉它缓存您喜欢的任何url
页面和软件之间的消息传递应该通过postMessage来实现。

我最后要做的是处理公共页面shared _Layout.cshtml中的逻辑。无论用户最初如何访问网站,通过fetch when need cache refresh timer查询数据库,并缓存动态页面,都会受到影响。因此,当用户导航到我想要缓存的页面时,页面是新鲜的

非常感谢@pate-我喜欢postMessage功能。这可能有点不符合实际情况,但我的需求更倾向于主动缓存特定页面,而URL在设计时恰好不为人所知。我的网站基本上需要特定的页面,当它们出现在主页上时可用-我可能错了,但你的解决方案是否倾向于在访问相关页面时“预热”页面?