2015-05-02 4 views
2

Я пытаюсь использовать сервисного работника в приложении Ruby on Rails.Ruby on Rails & service worker

Мне нужно использовать некоторые функции erb в моем файле app/javascripts/service-worker.js.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.js в папку public, удалите расширение .erb и изменять масштаб до ./, все отлично работает, но у меня нет механизма шаблонов.

Любые предложения?

ответ

1

Из-за цели безопасности вы не можете зарегистрировать ServiceWorker в более высокой области действия, чем от того, где он был выполнен.

Если вам действительно нужен механизм шаблонов, вы можете попробовать динамически загружать JS-файл из файла в вашу/общедоступную папку (How do I include a JavaScript file in another JavaScript file?). В настоящее время HTTP-заголовок, разрешенный для рабочих сервисов, еще не реализован в Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=1130101)

1

Просто сделайте это в корневом каталоге. Например, я ставлю маршрут

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

Тогда просто положить в контроллере (core_controller.rb в моем примере)

def service_worker 
end 

Затем создайте приложение/Views/ядро ​​/ service_worker.js.erb и положить ваш JS там (включая любой <% = материал%>).

1

Теперь я сталкиваюсь с этой проблемой. Основываясь на моих исследованиях, я считаю, что правильный подход для приложения Rails для работы с рабочими-сервисами заключается в том, чтобы обслуживать javascript-файл рабочего пользователя, обычно используя конвейер Asset, обладать услугами рабочего, используя параметр области (как вы это сделали), а затем использовать Service-Worker-Allowed HTTP header, чтобы явно разрешить новую область.

К сожалению, на данный момент существует ряд барьеров на пути реализации этого метода:

  1. Rails 4 (видимо) не позволяет добавлять HTTP-заголовки к активам, которые она обслуживает, кроме заголовка кэш-контроля. Чтобы обойти это, вы можете добавить плагин Rack, подробно описанный в этом S.O. answer, или в процессе производства, если вы используете сервер Asset, такой как Nginx, вы можете обойти это, добавив Nginx HTTP-заголовок. Хотя это не помогает во время разработки.
  2. Rails 5 позволяет добавлять заголовки HTTP в Assets, однако, как detailed in this blog post.
  3. Поддержка браузера для рабочих сервисов и HTTP-заголовка, разрешенного службой-работником, составляет currently poor.
+1

ли serviceworker рельсы камень упоминается в более поздний ответ (http://stackoverflow.com/a/36849798/1299792) устранить барьеры, вы упомянули выше? – Marklar

+0

@Marklar Я раньше не использовал этот драгоценный камень, но, глядя на него на Github, он, похоже, устраняет все барьеры, за исключением того факта, что поддержка браузеров для сервисных работников по-прежнему оставляет желать лучшего. Если бы я строил новое приложение для рельсов, используя сервисных работников, я бы определенно это выяснил. – John

3

Теперь есть драгоценный камень, serviceworker-rails, который позволит вам запрашивать прокси-запросы для сценариев serviceworker в конвейере активов.Из-за того, как браузеры регистрируют скрипты serviceworker, лучше избегать их кеширования.

Звездочки будут иметь отпечатки пальцев, а Rails (или ваш веб-сервер) обычно обслуживает скомпилированные файлы с агрессивными заголовками кеширования из каталога /assets.

Что мы хотим - это возможность настраивать пути рабочих работников и заголовки ответов и по-прежнему получают предварительную обработку Sprockets, то есть CoffeeScript/ES2015 для трансляции Java.

Вставка 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