如何在 Django REST Framework 上启用 CORS
- 2024-12-23 08:43:00
- admin 原创
- 93
问题描述:
如何在 Django REST Framework 上启用 CORS?参考资料没有多大帮助,它说我可以通过中间件来实现,但是我该怎么做呢?
解决方案 1:
您在问题中引用的链接建议使用django-cors-headers
,其文档说要安装库
python -m pip install django-cors-headers
然后将其添加到您已安装的应用程序中:
INSTALLED_APPS = (
...
'corsheaders',
...
)
您还需要添加一个中间件类来监听响应:
MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...,
]
并指定 CORS 的域,例如:
CORS_ALLOWED_ORIGINS = [
'http://localhost:3030',
]
请浏览其文档的配置部分,特别注意各种CORS_ORIGIN_
设置。您需要根据需要设置其中一些设置。
解决方案 2:
python -m pip install django-cors-headers
然后将其添加到您已安装的应用程序中:
INSTALLED_APPS = [
...
'corsheaders',
...
]
您还需要添加一个中间件类来监听响应:
MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...,
]
CORS_ALLOW_ALL_ORIGINS = True # If this is used then `CORS_ALLOWED_ORIGINS` will not have any effect
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
'http://localhost:3030',
] # If this is used, then not need to use `CORS_ALLOW_ALL_ORIGINS = True`
CORS_ALLOWED_ORIGIN_REGEXES = [
'http://localhost:3030',
]
更多详细信息:https ://github.com/ottoyiu/django-cors-headers/#configuration
阅读官方文档可以解决几乎所有问题
解决方案 3:
你可以使用自定义中间件来实现,尽管你知道最好的选择是使用经过测试的包方法django-cors-headers
。话虽如此,以下是解决方案:
创建以下结构和文件:
--myapp/middleware/__init__.py
from corsMiddleware import corsMiddleware
--myapp/middleware/corsMiddleware.py
class corsMiddleware(object):
def process_response(self, req, resp):
resp["Access-Control-Allow-Origin"] = "*"
return resp
添加到settings.py
标记行:
MIDDLEWARE_CLASSES = (
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
# Now we add here our custom middleware
'app_name.middleware.corsMiddleware' <---- this line
)
解决方案 4:
如果有人回到这个问题并决定编写自己的中间件,这是 Django 新型中间件的代码示例 -
class CORSMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
response["Access-Control-Allow-Origin"] = "*"
return response
解决方案 5:
对于 Django 版本 > 1.10,根据文档,可以将自定义 MIDDLEWARE 写为函数,比如在文件中:(yourproject/middleware.py
作为的兄弟settings.py
):
def open_access_middleware(get_response):
def middleware(request):
response = get_response(request)
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Headers"] = "*"
return response
return middleware
最后,将此函数的 python 路径(相对于项目的根目录)添加到项目的 MIDDLEWARE 列表中settings.py
:
MIDDLEWARE = [
.
.
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'yourproject.middleware.open_access_middleware'
]
非常简单!
解决方案 6:
对于拥有最新版本 Django v3.xx 的所有人,已更新至 2021 年,允许来自任何来源的 CORS 的步骤如下。
步骤 1:安装所需的库
pip install django-cors-headers
步骤 2:然后在INSTALLED_APPS中的适当位置添加settings.py
-在rest_framework
应用程序之后和之前myapp
'rest_framework',
'corsheaders',
'myapp.apps.MyAppConfig',
步骤 3:允许您的 API 的来源(内部settings.py
)
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000', # for localhost (REACT Default)
'http://192.168.10.45:3000', # for network
)
解决方案 7:
2022 年更新并添加新用例
当您使用带有选项的 Axios POST 时withCredentials: true
,还有一些其他选项需要考虑。
我使用这个特定案例来通过基本或/和会话登录进行身份验证。
为避免出现错误信息,请执行以下操作:
预检请求的响应未通过访问控制检查:响应中的 'Access-Control-Allow-Credentials' 标头的值为 '',当请求的凭据模式为 'include' 时,该值必须为 'true'。由 XMLHttpRequest 发起的请求的凭据模式由 withCredentials 属性控制。
以及其他人提到的上述内容。我通过这种方式解决了这个问题。
[IP 地址来自我的本地示例,打算更改它]
设置.py
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
'rest_framework.authtoken',
...
]
ALLOWED_HOSTS = ["localhost","192.168.0.50"]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000', # for localhost (REACT Default)
'http://192.168.0.50:3000', # for network
'http://localhost:8080', # for localhost (Developlemt)
'http://192.168.0.50:8080', # for network (Development)
)
CSRF_TRUSTED_ORIGINS = [
'http://localhost:3000', # for localhost (REACT Default)
'http://192.168.0.50:3000', # for network
'http://localhost:8080', # for localhost (Developlemt)
'http://192.168.0.50:8080', # for network (Development)
]
MIDDLEWARE = [
...
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsMiddleware',
...
]
在浏览器上,必须发送 Axios 请求标头,在服务器站点上必须允许该标头。如果不行,则会出现错误消息。
请求标头字段 access-control-allow-origin 不被预检响应中的 Access-Control-Allow-Headers 所允许。
到目前为止,请使用标题。如果需要,您可以添加更多标题,例如:
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
干杯 :)
解决方案 8:
以下是无需任何外部模块的工作步骤:
步骤 1:在您的应用程序中创建一个模块。
例如,假设我们有一个名为user_registration_app的应用程序。探索 user_registration_app 并创建一个新文件。
我们将其称为custom_cors_middleware.py
粘贴以下类定义:
class CustomCorsMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = self.get_response(request)
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Headers"] = "*"
# Code to be executed for each request/response after
# the view is called.
return response
步骤 2:注册中间件
在您的项目 settings.py 文件中,添加此行
'用户注册应用程序.custom_cors_middleware.CustomCorsMiddleware'
例如:
MIDDLEWARE = [
'user_registration_app.custom_cors_middleware.CustomCorsMiddleware', # ADD THIS LINE BEFORE CommonMiddleware
...
'django.middleware.common.CommonMiddleware',
]
请记住将user_registration_app替换为您创建 custom_cors_middleware.py 模块的应用程序的名称。
您现在可以验证它是否会将所需的响应标头添加到项目中的所有视图!
解决方案 9:
好吧,我不认识你们,但是:
这里使用 python 3.6 和 django 2.2
将 settings.py 中的 MIDDLEWARE_CLASSES 重命名为 MIDDLEWARE 即可。
解决方案 10:
首先安装 django 包
pip install django-cors-headers
并在设置文件中添加到应用程序
INSTALLED_APPS = (
...
'corsheaders',
...
)
然后将 cors 中间件添加到设置文件
MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...,
]
最后添加跨域白名单
#CORS_ORIGIN_ALLOW_ALL = True
#CORS_ALLOW_CREDENTIALS = True
#CORS_ALLOW_HEADERS = ['*']
CORS_ORIGIN_WHITELIST = ('http://localhost:5000',)
这将轻松解决 cors 错误。祝您编码愉快
解决方案 11:
尝试了所有建议的解决方案,但似乎都不起作用。经过一番折腾,我终于通过清除浏览器缓存解决了这个问题...
然后,通过使用 ,可以接受的答案起作用django-cors-headers
。
希望这对其他人有帮助!
清除缓存的 Shell 命令 -
find . -name '*.pyc' -type f -delete && find . | grep -E "(/__pycache__$|.pyc$|.pyo$)" | xargs rm -rf
解决方案 12:
Django=2.2.12 django-cors-headers=3.2.1 djangorestframework=3.11.0
按照官方说明操作无效
最后还是用老办法来解决。
添加:
# proj/middlewares.py
from rest_framework.authentication import SessionAuthentication
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
return # To not perform the csrf check previously happening
#proj/settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'proj.middlewares.CsrfExemptSessionAuthentication',
),
}
解决方案 13:
当我将 corsheaders.middleware.CorsMiddleware 作为中间件的最后一部分时,它对我有用
解决方案 14:
因此,考虑到我自己刚刚解决了这个问题,让我们来看看 CORS 可能出错的不同方式。
初步的
如果有人需要复习一下,CORS代表跨源资源共享,每当浏览器 JS 向其他网站发出 HTTP(S) 请求时就会触发它。它不会在浏览器之外施加此类限制。
启用 CORS 的后端将在响应中将多个标头发送回前端,其中之一是Access-Control-Allow-Origin
。此标头的值将是进行查询的前端的 URL(减去路径)。示例:https://example.com
等http://localhost:3000
。即使在使用 localhost 时也需要它,并且它可以正常工作,因为 URL 实际上并未被后端调用。它只是一个字符串,它会将其与 Django 中间件中指定的允许来源列表进行比较。
仅当请求中包含标头Access-Control-Allow-Origin
时,才会在响应中发送一个。所有浏览器都会发送此标头,出于安全原因,它不能更改。它只能是浏览器 URL 中指定的来源。您可以尝试使用 cURL 发出请求,并使用发送不同的值来查看响应是什么样的,但这超出了本文的范围。Origin
`-IH <origin>`
这只涉及如何使GET
请求正常工作。POST
并且PUT
请求还需要其他答案中解释的 CSRF 设置。
确保这确实是 CORS 的问题
有时,你的浏览器中可能会缓存 .pyc 文件或 HTTP 响应,这会让你认为 CORS 存在问题,但实际上它已经修复。为确保不存在这种情况,请执行以下操作:
使用此答案中的命令清除你的 pycache 。
打开浏览器设置,转到清除浏览数据部分,清除缓存的图像和文件。这还可以修复很多奇怪的错误,比如你从后端收到一种旧式的响应,但只发送到浏览器,而其他一切都正常。
摆脱重复的 CORS 条目
如果您在 Nginx 或 Apache 等反向代理后面运行生产 Django 服务器,则添加Access-Control-Allow-Origin
标头实际上可能会导致请求失败 CORS。发生这种情况的原因是 Django(通过中间件)和反向代理都Access-Control-Allow-Origin
在响应中添加一个,但浏览器期望的 HTTP 响应仅应接收此标头一次。如果您在开发人员工具控制台中看到类似这样的错误:
Access to XMLHttpRequest at 'https://example.com/api' from origin 'http://localhost:3000' has been blocked by CORS policy:
The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:3000, *', but only one is allowed.
那么这就是原因。即使您允许所有来源使用,也可能会发生此错误*
。
因此,我不建议在 Nginx 或其他反向代理中添加 CORS 标头,因为 Django 已经添加了这些标头。
确保 Django 具有 CORS
您需要按照此答案中的步骤操作(目前,这是公认的答案),即django-cors-headers
使用 Pip 安装,然后打开,settings.py
将其添加corsheaders
到INSTALLED_APPS
,然后corsheaders.middleware.CorsMiddleware
添加到MIDDLEWARE
。您不需要添加CommonMiddleware行,因为它已经存在于文件中,只需确保它位于下方即可CorsMiddleware
。
然后添加没有路径的前端 URLCORS_ALLOWED_ORIGINS
或仅设置CORS_ALLOW_ALL_ORIGNIS
为 True(不推荐)并重新启动 Django 或 WSGI 运行时。
如果您仍然遇到 CORS 错误
如果由于某种原因,浏览器没有看到Access-Control-Allow-Origin
响应标头并阻止了您的请求,请尝试以下操作:
清除浏览器缓存 - 它通常是罪魁祸首(对我来说是的)。
确保您没有其他中间件或 Nginx 设置与 CORS 设置冲突。
确保后端端点正常工作,不会因异常而抛出 5xx 错误。特别是如果您没有将其放在
CorsMiddleware
顶部,Django 可能会返回没有任何 CORS 标头的错误响应。一般来说,在尝试修复 CORS 错误之前,您应该确保您的后端没有错误 - 这将为您节省大量时间。
解决方案 15:
首先安装 django-cors-headers 包,将此命令添加到命令提示符或 power shell 等。
pip 安装 django-cors-headers
或
python -m pip 安装 django-cors-headers
在 settings.py 文件中,在 INSTALLED_APPS 中添加“corsheaders”
INSTALLED_APPS = [
...,
'corsheaders',
...,
]
在 settings.py 文件中,在 MIDDLEWARE 中添加“corsheaders.middleware.CorsMiddleware”
MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
...,
]
在 settings.py 文件中,在文件末尾添加以下内容
CORS_ALLOWED_ORIGINS = [
"http://localhost:5173", # Add your frontend URL here
]
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)