我正在尝试在Ruby on Rails应用程序中使用服务工作者。
我需要在app/javascripts/service-worker.js.erb
文件中使用某些erb功能。服务工作者注册脚本如下所示:
var registerServiceWorker = function() {
navigator.serviceWorker.register(
'<%= asset_path('service-worker.js') %>',
{ scope: '/assets/' }
)
.then(function() {
console.info('Service worker successfully registered');
})
.catch(function(error) {
console.warn('Cannot register sercie worker. Error = ', error);
});
}
这不起作用;我从来没有在这里得到承诺:
navigator.serviceWorker.ready.then
我还尝试了./
和/
范围但我收到了这个错误:
DOMException:无法注册ServiceWorker:路径 提供的范围('/')不在允许的最大范围('/ assets /')之下。 调整范围,移动Service Worker脚本或使用 Service-Worker-Allowed HTTP标头允许范围。
如果我将service-worker.js
移至public
文件夹,请移除.erb
扩展名并将范围更改为./
,一切正常,但我没有模板引擎
有什么建议吗?
答案 0 :(得分:4)
现在有一个gem serviceworker-rails
允许您在资产管道中代理对serviceworker脚本的请求。由于浏览器注册serviceworker脚本的方式,最好避免缓存它们。
Sprockets将指纹资产和Rails(或您的网络服务器)通常使用来自/assets
目录的积极缓存标头来提供编译文件。
我们想要的是能够自定义服务工作者路径和响应头和仍然可以进行Sprockets预处理,即CoffeeScript / ES2015到JavaScript的转换。
serviceworker-rails
gem将中间件插入到您的Rails堆栈中,该堆栈将/serviceworker.js
(例如)的请求代理到生产中相应的指纹编译资产。在开发过程中,您将获得所期望的自动重新加载行为。您也可以在不同的范围内设置多个服务工作者。
答案 1 :(得分:2)
出于安全目的,您不能在比执行范围更高的范围内注册ServiceWorker。
如果您确实需要模板引擎,可以尝试从/ public文件夹(How do I include a JavaScript file in another JavaScript file?)中的文件动态加载JS文件。目前,Firefox(https://bugzilla.mozilla.org/show_bug.cgi?id=1130101)
答案 2 :(得分:2)
我现在也遇到了这个问题。根据我的研究,我认为Rails应用程序处理服务工作者的正确方法是使用Asset管道正常服务于服务工作者javascript文件,使用scope选项对服务工作者进行范围调整(就像你已经完成的那样),然后使用Service-Worker-Allowed HTTP header明确允许新范围。
不幸的是,目前实施此方法存在一些障碍:
答案 3 :(得分:1)
只需在根目录中执行即可。例如,我放了一条路线
get 'service-worker(.format)', to: 'core#service_worker'
然后只需放入你的控制器(我的例子中的core_controller.rb)
def service_worker
end
然后创建app / views / core / service_worker.js.erb并将你的JS放在那里(包括任何&lt;%= stuff%&gt;)。
答案 4 :(得分:0)
将服务工作者文件保留在项目结构强加的任何目录中,并将scope
选项设置为/
,并将Service-Worker-Allowed
HTTP标头添加到服务工作者文件的响应中。
在ASP.Net中,我将以下内容添加到web.config文件中:
<location path="assets/serviceWorker.js">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Service-Worker-Allowed" value="/" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
通过以下方式注册工人:
navigator.serviceWorker.register('/assets/serviceWorker.js', { scope: '/' })
.then(function (registration)
{
console.log('Service worker registered successfully');
}).catch(function (e)
{
console.error('Error during service worker registration:', e);
});
在Firefox和Chrome上测试过。
中的示例答案 5 :(得分:0)
我最近写了一篇关于如何完全使用Webpacker做到这一点的文章。请找到我的Progressive Web App with Rails指南。 简而言之:
使用yarn add webpacker-pwa
添加webpacker-pwa npm软件包,并使用以下命令编辑environment.js
:
const { resolve } = require('path');
const { config, environment, Environment } = require('@rails/webpacker');
const WebpackerPwa = require('webpacker-pwa');
new WebpackerPwa(config, environment);
module.exports = environment;
这将使您可以使用服务人员。请同时检查项目的自述文件:https://github.com/coorasse/webpacker-pwa/tree/master/npm_package