首页 > 解决方案 > Rails 渐进式 Web 应用程序问题

问题描述

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

这导致了我的问题:注册服务工作者的脚本资源位于重定向后面并且无法访问它,这就是服务工作者没有被加载并且用户无法使用 PWA 的功能的原因。

这是我在 application.js 中注册工作人员的代码:

    if (navigator.serviceWorker) {
    navigator.serviceWorker.register('/service-worker.js', { scope: './' })
                           .then(function(registration) {
                             console.log('[Companion]', 'Service worker registered!')
                             console.log(registration)
                           })
}

然后我使用两个控制器的方法,一个用于清单文件,另一个用于重定向到相应视图/文件的服务人员。

在我的头标签中,我添加<link rel="manifest" href="/manifest.json">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);  

访问应用程序以供外部使用时,我在浏览器中遇到的错误如下:

脚本资源位于重定向后面,这是不允许的。

未捕获(承诺)DOMException:无法使用脚本(' https://xxxxxxx.nkbrf.de/service-worker.js ')为范围(' https://xxxxxxx.nkbrf.de/ ')注册 ServiceWorker :脚本资源位于重定向后面,这是不允许的。

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

谢谢你的帮助!

标签: ruby-on-railsservice-workerprogressive-web-apps

解决方案


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

根据 Mozilla 网站:

范围参数是可选的,可用于指定您希望服务工作者控制的内容子集。在这种情况下,我们指定了“/sw-test/”,表示应用程序源下的所有内容。如果您忽略它,无论如何它都会默认为该值,但我们在此处指定它是为了便于说明。

https://developer.mozilla.org/pt-BR/docs/Web/API/Service_Worker_API/Using_Service_Workers


推荐阅读