2015-05-02 111 views
2

我想在我的Ruby on Rails应用程序中使用服务工作者。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: Failed to register a ServiceWorker: The path of the provided scope ('/') is not under the max scope allowed ('/assets/'). Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope.

如果我提出我的service-worker.jspublic文件夹,删除.erb延伸和变化范围到./,一切都很好,但我没有模板引擎。

有什么建议吗?

回答

1

只需在根目录中执行即可。例如,我把路线

get 'service-worker(.format)', to: 'core#service_worker' 

然后,只需把你的控制器(在我的例子core_controller.rb)

def service_worker 
end 

然后创建应用程序/视图/核心/ service_worker.js.erb放你的JS在那里(包括任何<%= stuff%>)。

1

我现在也遇到了这个问题。根据我的研究,我认为Rails应用程序处理服务工作人员的正确方法是使用Asset管道正常提供服务工作人员JavaScript文件,使用范围选项来限定服务工作人员(就像您所做的那样),然后使用Service-Worker-Allowed HTTP header明确允许新的范围。

不幸的是,目前有几种障碍实现该方法:

  1. 导轨4(显然)不允许添加HTTP标头所服务的资产,比高速缓存控制报头的其他。要解决这个问题,您可以添加一个Rack插件,如S.O. answer中详细描述的那样,如果您使用的是像Nginx这样的资源服务器,那么您可以通过让Nginx添加HTTP标头来解决此问题。尽管这在开发过程中没有帮助。
  2. Rails 5确实允许将HTTP标头添加到资产,但是,因为detailed in this blog post
  3. 服务人员和服务工作者允许的HTTP标头的浏览器支持为currently poor
+1

是否在以后的答复中提到的serviceworker护栏宝石(http://stackoverflow.com/a/36849798/1299792)解决您上面提到的障碍是什么? – Marklar

+0

@Marklar我之前没有使用过那个gem,但是,在Github看来,它似乎解决了所有的障碍,除了浏览器对服务工作者的支持仍然很差的事实。如果我正在使用服务人员构建一个新的Rails应用程序,我一定会检查出来。 – John

3

现在有一个gem,serviceworker-rails,它允许您在资产管道中代理serviceworker脚本的请求。由于浏览器注册serviceworker脚本的方式,最好避免缓存它们。

链轮将指纹资产和Rails(或您的网络服务器)通常提供从/assets目录积极的缓存标头编译的文件。

我们想要的是定制服务工作程序路径和响应标头的能力仍然会获得Sprockets预处理,即CoffeeScript/ES2015转换为JavaScript。

serviceworker-rails gem将中间件插入到您的Rails堆栈中,该堆栈将代理请求/serviceworker.js(例如)到生产中的相应指纹编译资产。在开发中,您会得到您期望的自动重新加载行为。您也可以在不同的范围设置多个服务工作者。

https://github.com/rossta/serviceworker-rails

+0

轻松获得最佳解决方案 –

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。

参考例子Service worker specification