Django и сервисные работники - подают "sw.js" в корневой URL-адрес приложения

Поэтому я создаю прогрессивное веб-приложение Django с поддержкой в ​​автономном режиме с использованием сервисных работников.

Согласно документации Google, файл sw.js должен находиться в корне URL-адреса приложения:

Это необходимо сделать, потому что область действия работника службы (набор URL-адресов, для которых будет загружен ServiceWorker) определяется каталогом, в котором он находится.

На данный момент я обслуживаю все статические ресурсы из папки http://example.com/static/. Но мне нужно предоставить этот конкретный файл по URL-адресу, например: http://example.com/sw.js.

Есть идеи, как мне этого добиться? Я мог бы сделать конкретное правило nginx, чтобы сделать это перенаправление, но я не знаю, является ли это самым чистым способом сделать это. Может быть, этот параметр должен находиться в urls.py?

Примечание: я видел этот вопрос, который предлагает использовать метод static() из django.conf.urls.static, Но в документах django говорится, что статический метод предназначен только для разработки, поэтому он мне не подходит.

Примечание (2): я думаю, я мог бы изменить STATIC_URL настройки, но я доволен тем, что мои файлы обслуживаются из каталога / static. Я только хочу, чтобы этот файл был в корне URL.

2 ответа

Вы можете использовать JavaScript как представление, а не только HTML. Поместите это в свои проекты urls.py

url(r'^service-worker.js', cache_control(max_age=2592000)(TemplateView.as_view(
    template_name="service-worker.js",
    content_type='application/javascript',
)), name='service-worker.js'),

Тогда положи service-worker.js в вашем каталоге шаблонов.

Бонус в том, что теперь вы также можете использовать шаблоны тегов, такие как статические, в вашем файле JavaScript.

Джанго 2.2

структура проекта

myproj/
|-app/
| |-templates/
|   |-app/
|     -sw.js
|-myproj/
  -urls.py

urls.py (проект)

from django.views.generic import TemplateView

urlpatterns = [
  ...
  path('sw.js', (TemplateView.as_view(template_name="app/sw.js", 
  content_type='application/javascript', )), name='sw.js'),
]

В Django 1.11 должен выглядеть urls.py:

from django.views.generic import TemplateView

urlpatterns = [
  url(r'^sw.js', (TemplateView.as_view(template_name="sw.js", content_type='application/javascript', )), name='sw.js'),
]

Я все время получал ошибку DOMException: The script resource is behind a redirect, which is disallowed.

Я часами пытался найти решение.

Помимо добавления в urls.py:

from django.views.generic import TemplateView

urlpatterns = [
  ...,
  url(r'^service-worker.js', (TemplateView.as_view(template_name="service-worker.js", content_type='application/javascript', )), name='service-worker.js'),
]

Также был необходим еще один шаг. Вместо того

<script>
 if ('serviceWorker' in navigator) {
    console.log("Will the service worker register?");
    navigator.serviceWorker.register('service-worker.js')
      .then(function(reg){
        console.log("Yes, it did.");
     }).catch(function(err) {
       console.log("No it didn't. This happened:", err)
        console.log("err.message:", err.message)
    });
 }
</script>

Я использовал:

<script>
 if ('serviceWorker' in navigator) {
    console.log("Will the service worker register?");
    navigator.serviceWorker.register("{% url 'service-worker.js' %}") //note that I am using the url template here
      .then(function(reg){
        console.log("Yes, it did.");
     }).catch(function(err) {
       console.log("No it didn't. This happened:", err)
        console.log("err.message:", err.message)
    });
 }
</script>
Другие вопросы по тегам