如何在 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-cor...

问题描述:

如何在 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.comhttp://localhost:3000。即使在使用 localhost 时也需要它,并且它可以正常工作,因为 URL 实际上并未被后端调用。它只是一个字符串,它会将其与 Django 中间件中指定的允许来源列表进行比较。

仅当请求中包含标头Access-Control-Allow-Origin时,才会在响应中发送一个。所有浏览器都会发送此标头,出于安全原因,它不能更改。它只能是浏览器 URL 中指定的来源。您可以尝试使用 cURL 发出请求,并使用发送不同的值来查看响应是什么样的,但这超出了本文的范围。Origin`-IH <origin>`

这只涉及如何使GET请求正常工作。POST并且PUT请求还需要其他答案中解释的 CSRF 设置。

确保这确实是 CORS 的问题

有时,你的浏览器中可能会缓存 .pyc 文件或 HTTP 响应,这会让你认为 CORS 存在问题,但实际上它已经修复。为确保不存在这种情况,请执行以下操作:

  1. 使用此答案中的命令清除你的 pycache 。

  2. 打开浏览器设置,转到清除浏览数据部分,清除缓存的图像和文件。这还可以修复很多奇怪的错误,比如你从后端收到一种旧式的响应,但只发送到浏览器,而其他一切都正常。

摆脱重复的 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将其添加corsheadersINSTALLED_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:

  1. 首先安装 django-cors-headers 包,将此命令添加到命令提示符或 power shell 等。

pip 安装 django-cors-headers

python -m pip 安装 django-cors-headers

  1. 在 settings.py 文件中,在 INSTALLED_APPS 中添加“corsheaders”

INSTALLED_APPS = [
    ...,
    'corsheaders',
    ...,
]
  1. 在 settings.py 文件中,在 MIDDLEWARE 中添加“corsheaders.middleware.CorsMiddleware”

MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
...,
]
  1. 在 settings.py 文件中,在文件末尾添加以下内容

CORS_ALLOWED_ORIGINS = [
    "http://localhost:5173",  # Add your frontend URL here
]
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1120  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   75  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   66  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   76  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   70  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用