Django and service workers - serve “sw.js” at application's root url

冷暖自知 提交于 2019-11-27 03:25:22

问题


So I'm building a Django progressive web app with offline support using service workers.

According to google's documentation, the sw.js file should be at the root of the app's url:

You need to do this because the scope of a service worker (the set of urls that the ServiceWorker will load for) is defined by the directory where it resides.

At the moment, I'm serving all static assets from http://example.com/static/ folder. But I need to serve this specific file at a url like: http://example.com/sw.js.

Any idea how I can achieve this? I could make a specific nginx rule to do this redirection, but I don't know if it's the cleanest way of doing this. Maybe this setting should reside in urls.py?

Note: I've seen this question which suggests using the static() method from django.conf.urls.static. But django's docs say that the static method is only for development use so not good for me.

Note (2): I guess I could change the STATIC_URL setting, but I'm happy with my files being served from /static directory. I only want this one file to be at url's root.


回答1:


You can serve javascript as a view, not just html. Put this in your projects 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'),

Then put your service-worker.js in your templates directory.

Bonus is that you can now also use template tags like static in your javascript file.




回答2:


In Django 1.11 urls.py should look:

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



回答3:


Django 2.2

project structure

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

urls.py (project)

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



回答4:


I was getting all the time the error DOMException: The script resource is behind a redirect, which is disallowed.

I spent hours trying to figure out the solution.

Apart from adding at 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'),
]

There was also another step needed. Instead of

<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>

I used:

<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>


来源:https://stackoverflow.com/questions/38696595/django-and-service-workers-serve-sw-js-at-applications-root-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!