加载 Django 运行服务器提供的静态文件时如何修复 cors 错误
How to fix cors error when loading static file served by Django runserver
相关信息:Django 版本 2.2
我已经安装 django-cors-headers
并将其添加到已启用的应用程序中,并将中间件作为第一个中间件添加到中间件设置中。
我也配置了设置:
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
我的设置在不同的端口上有 2 个项目 运行。 Django 服务器 运行 在 8000 上,我的前端 运行 在 8080 上。
所有 API 请求前端发送反对后端工作就好了。但是当我尝试加载由后端项目提供的 one.js 文件时,它失败并出现此错误:
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)
我加载脚本的方式是创建一个新的脚本元素并添加 URL http://127.0.0.1:8000/static/myscript.js
作为脚本标签上 src 属性的值。
当我使用 https://code.jquery.com/jquery-3.5.1.min.js
之类的值而不是 http://127.0.0.1:8000/static/myscript.js
时,不会发生此错误,因此看起来 Django runserver 提供的静态文件存在一些问题,但到底是什么以及为什么超出我的范围。
我知道有很多与 cors 相关的问题,例如 Django CORS on static asset,但它们与我的问题无关或没有得到解答。另外,我注意到,对静态文件的请求无论如何都会绕过 cors 中间件,所以也许我应该在这里做些其他事情?
也许有人可以帮助我?
谢谢
看来我找到了答案:
我所做的是将 INSTALLED_APPS.remove('django.contrib.staticfiles')
添加到开发设置中。
并且我创建了类似
的视图
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
用于提供静态内容。我像这样将它添加到 urlconf 中:
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)
这确实为我解决了这个问题。我知道 Django 文档 (https://docs.djangoproject.com/en/2.2/ref/contrib/staticfiles/#runserver) 建议您可以像这样使用 runserver 跳过静态文件服务:django-admin runserver --nostatic
但如果我仍然有 "django.contrib.staticfiles"
,那对我来说绝对没有影响我的 INSTALLED_APPS
一种基于 Odif Yitsaeb 想法的略有不同的方法,但是您不需要删除 staticfiles
或弄乱 urlpatterns
。只需将以下代码放入您的 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
备注:
- 不要在生产中使用它(无论如何你都不应该在生产中使用 devserver)
- 处理程序必须尽早进行 monkeypatched,在处理任何请求之前。将代码放在
settings.py
中就可以了
相关信息:Django 版本 2.2
我已经安装 django-cors-headers
并将其添加到已启用的应用程序中,并将中间件作为第一个中间件添加到中间件设置中。
我也配置了设置:
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
我的设置在不同的端口上有 2 个项目 运行。 Django 服务器 运行 在 8000 上,我的前端 运行 在 8080 上。
所有 API 请求前端发送反对后端工作就好了。但是当我尝试加载由后端项目提供的 one.js 文件时,它失败并出现此错误:
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)
我加载脚本的方式是创建一个新的脚本元素并添加 URL http://127.0.0.1:8000/static/myscript.js
作为脚本标签上 src 属性的值。
当我使用 https://code.jquery.com/jquery-3.5.1.min.js
之类的值而不是 http://127.0.0.1:8000/static/myscript.js
时,不会发生此错误,因此看起来 Django runserver 提供的静态文件存在一些问题,但到底是什么以及为什么超出我的范围。
我知道有很多与 cors 相关的问题,例如 Django CORS on static asset,但它们与我的问题无关或没有得到解答。另外,我注意到,对静态文件的请求无论如何都会绕过 cors 中间件,所以也许我应该在这里做些其他事情?
也许有人可以帮助我?
谢谢
看来我找到了答案:
我所做的是将 INSTALLED_APPS.remove('django.contrib.staticfiles')
添加到开发设置中。
并且我创建了类似
的视图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
用于提供静态内容。我像这样将它添加到 urlconf 中:
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)
这确实为我解决了这个问题。我知道 Django 文档 (https://docs.djangoproject.com/en/2.2/ref/contrib/staticfiles/#runserver) 建议您可以像这样使用 runserver 跳过静态文件服务:django-admin runserver --nostatic
但如果我仍然有 "django.contrib.staticfiles"
,那对我来说绝对没有影响我的 INSTALLED_APPS
一种基于 Odif Yitsaeb 想法的略有不同的方法,但是您不需要删除 staticfiles
或弄乱 urlpatterns
。只需将以下代码放入您的 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
备注:
- 不要在生产中使用它(无论如何你都不应该在生产中使用 devserver)
- 处理程序必须尽早进行 monkeypatched,在处理任何请求之前。将代码放在
settings.py
中就可以了