Ruby on rails Rails渐进式Web应用程序问题

Ruby on rails Rails渐进式Web应用程序问题,ruby-on-rails,service-worker,progressive-web-apps,Ruby On Rails,Service Worker,Progressive Web Apps,我正在尝试在Rails 6应用程序中实现一个渐进的web应用程序功能,它首先工作得很好。我正在为一家医院开发一个应用程序,该应用程序也可以从医院外部访问,因此我们决定将DMZ中的外部请求重定向到我的Web服务器 这导致了我的问题:注册服务工作者的脚本资源位于重定向后面,无法访问它,这就是为什么服务工作者无法加载,用户无法使用PWA的功能 下面是我在application.js中注册worker的代码: if (navigator.serviceWorker) { navigato

我正在尝试在Rails 6应用程序中实现一个渐进的web应用程序功能,它首先工作得很好。我正在为一家医院开发一个应用程序,该应用程序也可以从医院外部访问,因此我们决定将DMZ中的外部请求重定向到我的Web服务器

这导致了我的问题:注册服务工作者的脚本资源位于重定向后面,无法访问它,这就是为什么服务工作者无法加载,用户无法使用PWA的功能

下面是我在application.js中注册worker的代码:

    if (navigator.serviceWorker) {
    navigator.serviceWorker.register('/service-worker.js', { scope: './' })
                           .then(function(registration) {
                             console.log('[Companion]', 'Service worker registered!')
                             console.log(registration)
                           })
}
然后我使用两个控制器的方法,一个用于清单文件,另一个用于重定向到相应视图/文件的服务工作者

在我的头标签中,我在
application.html.erb
中添加了

我的路线如下:

get '/service-worker.js', to: 'service_workers/workers#index'
get '/manifest.json', to: 'service_workers/manifests#index'
这是我的service-worker.js:

var CACHE_VERSION = 'v1';
var CACHE_NAME = CACHE_VERSION + ':sw-cache-';

function onInstall(event) {
  console.log('[Serviceworker]', "Installing!", event);
  event.waitUntil(
    caches.open(CACHE_NAME).then(function prefill(cache) {
      return cache.addAll([
        '<%= asset_pack_path 'application.js' %>',
        '<%= root_path %>',
        '/mealplan',
      ]);
    })
  );
}

function onActivate(event) {
  console.log('[Serviceworker]', "Activating!", event);
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.filter(function(cacheName) {
          // Return true if you want to remove this cache,
          // but remember that caches are shared across
          // the whole origin
          return cacheName.indexOf(CACHE_VERSION) !== 0;
        }).map(function(cacheName) {
          return caches.delete(cacheName);
        })
      );
    })
  );
}

// Borrowed from https://github.com/TalAter/UpUp
function onFetch(event) {
  event.respondWith(
    // try to return untouched request from network first
    fetch(event.request).catch(function() {
      // if it fails, try to return request from the cache
      return caches.match(event.request).then(function(response) {
        if (response) {
          return response;
        }
        // if not found in cache, return default offline content for navigate requests
        if (event.request.mode === 'navigate' ||
          (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) {
          console.log('[Serviceworker]', "Fetching offline content", event);
          return caches.match('/offline.html');
        }
      })
    })
  );
}

self.addEventListener('install', onInstall);
self.addEventListener('activate', onActivate);
self.addEventListener('fetch', onFetch);  
var CACHE_VERSION='v1';
var CACHE_NAME=CACHE_VERSION+':sw CACHE-';
函数onInstall(事件){
日志(“[Serviceworker]”,“Installing!”,事件);
event.waitill(
caches.open(CACHE\u NAME)。然后(函数prefill(CACHE){
返回cache.addAll([
'',
'',
“/mealplan”,
]);
})
);
}
激活功能(事件){
日志(“[Serviceworker]”,“激活!”,事件);
event.waitill(
caches.keys().then(函数(cacheNames){
回报你的承诺(
过滤器(函数(cacheName){
//如果要删除此缓存,则返回true,
//但请记住,缓存是跨服务器共享的
//全部起源
返回cacheName.indexOf(CACHE\u版本)!==0;
}).map(函数(缓存名称){
返回缓存。删除(缓存名称);
})
);
})
);
}
//借来https://github.com/TalAter/UpUp
函数onFetch(事件){
事件响应(
//首先尝试从网络返回未触及的请求
fetch(event.request).catch(function(){
//如果失败,请尝试从缓存返回请求
返回caches.match(事件.请求).then(函数(响应){
如果(答复){
返回响应;
}
//如果在缓存中找不到,则返回导航请求的默认脱机内容
如果(event.request.mode===‘导航’||
(event.request.method=='GET'&&event.request.headers.GET('accept')。includes('text/html')){
log(“[Serviceworker]”,“获取脱机内容”,事件);
返回caches.match('/offline.html');
}
})
})
);
}
self.addEventListener('install',onInstall);
self.addEventListener('activate',onActivate);
self.addEventListener('fetch',onFetch);
访问外部使用的应用程序时,我在浏览器中遇到的错误如下:

get '/service-worker.js', to: 'service_workers/workers#index'
get '/manifest.json', to: 'service_workers/manifests#index'
脚本资源位于不允许的重定向后面

未捕获(在承诺中)DomeException:无法使用脚本(“”)为作用域(“”)注册ServiceWorker:脚本资源位于重定向后面,这是不允许的

我认为scope属性可能是问题所在,但我不想将其设置为固定值。有没有办法解决这个问题


谢谢你的帮助

如果删除scope属性,错误会消失吗?执行此测试,因为scope属性是可选的,并且在您的情况下,不必是不同的

根据Mozilla网站:

scope参数是可选的,可用于指定希望服务人员控制的内容子集。在本例中,我们指定了“/sw test/”,这意味着应用程序源下的所有内容。如果不使用它,它将默认为该值,但我们在此处指定它是为了进行说明


我在这里发现了一个类似的RoR问题:

为了使重定向正常工作(我也不能使用它们),我必须对上面列出的示例中提供的代码进行两次修改

  • 我必须在ruby内部获取“scope”的值(因此,index.json变成了index.json.erb),并且必须将该值设置为URI.join,

  • 接下来,我必须将routes.rb中的service-worker.js完全限定为我的workers文件的完整路径。
    get”/service-worker.js,“xyz\u abc/service\u-workers/workers\show”

  • 最后,我必须在父资源中为我的两个文件命名名称空间和资源:


  • 这三个步骤帮助我完成了。

    我想查看您的文件
    service worker.js的内容,可能此文件中有错误。另外,我认为这是一个小错误,但在您的消息中:
    未能为范围注册ServiceWorker(
    )https://xxxxxxx/service-worker.js“)和脚本('https://xxxxxx/service-worker.js')
    ,此
    https://xxxxxxx/service-worker.js
    与此
    https://xxxxxxx/service-worker.js
    。在最后一个URL中缺少一个字符。不,我只是不想显示真实的URL,这就是为什么我刚刚删除了它并键入了一些“x”字符。真实的URL在两种情况下都是相同的:)Mh确实,如果我删除了cope in my application.js正在运行。感谢您的提示:)