Django和服务工作者 - 在应用程序的根URL上提供“sw.js”

时间:2016-08-01 10:31:47

标签: django django-urls django-staticfiles service-worker

因此,我正在使用服务工作者构建一个支持离线支持的Django渐进式Web应用程序。

根据google's documentation,sw.js文件应位于应用网址的根目录下:

  

您需要这样做,因为服务工作者的范围(一组   ServiceWorker将加载的URL)由目录定义   它居住的地方。

目前,我正在为http://example.com/static/文件夹中的所有静态资源提供服务。但我需要在以下网址提供此特定文件:http://example.com/sw.js

知道如何实现这一目标吗?我可以制定一个特定的nginx规则来执行此重定向,但我不知道这是否是最干净的方法。也许这个设置应该存在于urls.py中?

注意:我看到this question建议使用django.conf.urls.static中的static()方法。但django's docs表示静态方法仅供开发使用,对我不利。

注意(2):我想我可以更改STATIC_URL设置,但我对从/ static目录提供的文件感到满意。我只希望这个文件位于url的根目录。

4 个答案:

答案 0 :(得分:14)

您可以将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文件中使用像static这样的模板标签。

答案 1 :(得分:1)

在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'),
]

答案 2 :(得分:0)

Django 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'),
]

答案 3 :(得分:0)

我一直都在遇到错误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>