如何解决我的 Django API 的 CORS 问题?

Posted

技术标签:

【中文标题】如何解决我的 Django API 的 CORS 问题?【英文标题】:How to solve CORS problem of my Django API? 【发布时间】:2019-04-07 01:29:06 【问题描述】:

我无法在我的 Django API 中解决 CORS 问题。当我调用此 API 时,出现错误:

从原点获取 'http://localhost:8000/' 的访问权限 “http://localhost”已被 CORS 策略阻止:响应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式为“no-cors”以获取禁用 CORS 的资源。

为了启用 CORS,我做了pip install django-cors-headers 并将以下代码添加到settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',
]

MIDDLEWARE_CLASSES = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ORIGIN_WHITELIST = [
    'localhost:80',
    'localhost:8000',
    '127.0.0.1:8000'
]

我应该说我在 Docker 上运行我的项目。这是docker-compose.yml

version: '2'

services:
  django-docker:
    build:
      context: .
      dockerfile: Dockerfile.django
    container_name: my.django
    image: my-django
    ports:
      - 8000:8000

  webapp-docker:
    build:
      context: .
      dockerfile: Dockerfile.webapp
    container_name: my.webapp
    image: my-web
    ports:
      - 80:80

【问题讨论】:

【参考方案1】:

您需要将corsheaders.middleware.CorsMiddleware中间件添加到settings.py中的中间件类中:

MIDDLEWARE_CLASSES = (
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.BrokenLinkEmailsMiddleware',
    'django.middleware.common.CommonMiddleware',
    #...
)

您的中间件类中有重复的django.middleware.common.CommonMiddleware

然后,您可以通过添加以下设置为所有域启用 CORS:

CORS_ORIGIN_ALLOW_ALL = True

或仅对指定域启用 CORS:

CORS_ORIGIN_ALLOW_ALL = False

CORS_ORIGIN_WHITELIST = (
    'http://localhost:8000',
)

【讨论】:

该死的你,':' 在 http 之后而不是在 localhost 之前。花了一个小时弄清楚:D。 +1 我刚刚花了一周时间调试一个令人讨厌的 CORS 问题。请注意,当您获得授权时,您不能允许全部。另外 - MIDDLEWARE_CLASSES 现在被称为 MIDDLEWARE。 如果您遇到罕见的 API 没有任何身份验证的情况,您可能还需要设置 CORS_ALLOW_CREDENTIALS = False(来自 ***.com/a/28834566/1927853)【参考方案2】:

尝试将其添加到您的设置中:

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
    'Access-Control-Allow-Origin',
)

【讨论】:

如果您想快速解决此问题,请添加:CORS_ORIGIN_ALLOW_ALL = True。但是,这不是推荐的生产设置。您是否尝试在 CORS_ORIGIN_WHITELIST 中设置容器的名称?【参考方案3】:

当我在浏览器中访问 http://127.0.0.1:8000 但在我的 javascript 代码中使用 fetch('http://localhost:8000'); 时出现此错误。解决方案是使用127.0.0.1localhost,但不要混合使用。

【讨论】:

这不起作用,因为当您使用不同的端口时,它会被视为不同的域。 @Spartacus 在我的情况下,端口是相同的,但我使用的是不同的域(即使它们通常意味着相同的东西)。如果端口不同,那么您是正确的,这不会解决问题。即使使用不同的端口,建议始终使用localhost127.0.0.1,但不要混合使用它们。

以上是关于如何解决我的 Django API 的 CORS 问题?的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的 Django REST api 上调试启用 CORS

我的请求是跨源请求吗?(heroku 上的 Django rest api,CORS 没有阻止我的请求)

当我的目标是动态时如何解决 Rest API 的 CORS 错误

如何解决 Fetch API js 中的 CORS 错误

如何使用 Angular 7 在 django1.1 中启用 cors?

使用 Nuxtjs 访问 Django api 时出现 CORS 错误 [重复]