3

Relevant info : Django version 2.2

I have installed django-cors-headers and added it to enabled apps and added the middleware to middleware settings as first middleware.

I have also configured the settings:


INSTALLED_APPS = [
    ...
    "corsheaders",
    "rest_framework",
    "django.contrib.admin",
    ...
]


MIDDLEWARE = [
    ...
    "corsheaders.middleware.CorsMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    ...
]

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

My setup has 2 projects running on different ports. Django server running on 8000 and my front-end running on 8080.

All API requests the front-end sends against back-end work just fine. But when I try to load one.js file served by the back-end project it fails with this error:


Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8000/static/myscript.js. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)

The way I load the script is by creating a new script element and add the URL http://127.0.0.1:8000/static/myscript.js as value for the src attribute on the script tag.

This error does not occur when I use a value like https://code.jquery.com/jquery-3.5.1.min.js instead of http://127.0.0.1:8000/static/myscript.js so it looks like there is some issue with static files being served by Django runserver, but what exactly and why is beyond me.

I know that there is a bunch of cors related issues like Django CORS on static asset, but they are not about my issue or have gone unanswered. Also, I noticed, that the requests going at static files bypass the cors middleware anyway, so perhaps I should be doing something else here instead?

Perhaps someone can help me out here?

Thanks

Odif Yltsaeb
  • 5,575
  • 12
  • 49
  • 80

2 Answers2

6

A slightly different approach based on Odif Yitsaeb's idea, however you don't need to remove staticfiles or mess with urlpatterns. Simply place the following code into your settings.py:

from django.contrib.staticfiles import handlers

# extend StaticFilesHandler to add "Access-Control-Allow-Origin" to every response
class CORSStaticFilesHandler(handlers.StaticFilesHandler):
    def serve(self, request):
        response = super().serve(request)
        response['Access-Control-Allow-Origin'] = '*'
        return response

# monkeypatch handlers to use our class instead of the original StaticFilesHandler
handlers.StaticFilesHandler = CORSStaticFilesHandler

Notes:

  • Don't use that in production (you shouldn't use devserver in production anyway)
  • The handler must be monkeypatched very early, before any requests are served. Placing the code in settings.py will do the trick
chrisv
  • 1,447
  • 17
  • 21
0

It looks like I have sort of found the answer:

What I did was I added INSTALLED_APPS.remove('django.contrib.staticfiles') into dev settings.

and I created view like

from django.contrib.staticfiles.views import serve


def cors_serve(request, path, insecure=False, **kwargs):
    kwargs.pop('document_root')
    response = serve(request, path, insecure=insecure, **kwargs)
    response['Access-Control-Allow-Origin'] = '*'
    return response

for serving static content. And I added it into urlconf like this:

from utils.views import cors_serve

...

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT, view=cors_serve)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT, view=cors_serve)

This does take care of the issue for me. I know that the Django docs (https://docs.djangoproject.com/en/2.2/ref/contrib/staticfiles/#runserver) suggest that you can skip static files serving with using runserver like this: django-admin runserver --nostatic but that had absolutely no effect for me if I still had "django.contrib.staticfiles" in my INSTALLED_APPS

Odif Yltsaeb
  • 5,575
  • 12
  • 49
  • 80