42

django-cors-headers 不起作用

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.gis',
    'corsheaders',
    'rest_framework',
    'world',
    'userManager',
    'markPost',
    'BasicServices',
)


MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    '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_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

一切正常,但没有工作

这是我的响应标题

Cache-Control: max-age=0
Content-Type: text/html; charset=utf-8
Date: Tue, 20 Jan 2015 13:16:17 GMT
Expires: Tue, 20 Jan 2015 13:16:17 GMT
Last-Modified: Tue, 20 Jan 2015 13:16:17 GMT
Server: WSGIServer/0.1 Python/2.7.8
Set-Cookie: csrftoken=snXksqpljbCLW0eZ0EElFxKbiUkYIvK0; expires=Tue, 19-Jan-2016 13:16:17 GMT; Max-Age=31449600; Path=/
Vary: Cookie
X-Frame-Options: SAMEORIGIN
4

17 回答 17

21

根据CorsMiddleware的 process_response 代码:

response[ACCESS_CONTROL_ALLOW_ORIGIN] = "*" if (
            settings.CORS_ORIGIN_ALLOW_ALL and
            not settings.CORS_ALLOW_CREDENTIALS) else origin

您必须像这样设置设置:

# CORS Config
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = False
于 2015-03-03T14:39:45.137 回答
20

我遇到了同样的问题,一切似乎都在正确的位置。然后我发现我在添加'corsheaders.middleware.CorsMiddleware',MIDDLEWARE_CLASSES. 改正后还是不行。在尝试了一堆东西之后,我在另一个浏览器中打开它并且它有效。所以原来我只需要清除浏览器缓存。

于 2019-04-18T18:58:54.203 回答
17

不要忘记添加

'corsheaders.middleware.CorsMiddleware',

在 MIDDLEWARE 变量的顶部:

请参阅文档:

CorsMiddleware 应该放在尽可能高的位置,尤其是在任何可以生成响应的中间件之前,例如 Django 的 CommonMiddleware 或 Whitenoise 的 WhiteNoiseMiddleware。如果不是之前,它将无法将 CORS 标头添加到这些响应中。

于 2018-01-05T15:02:45.103 回答
11

如果您正在对此进行测试,您需要确保在请求中至少包含 Origin 标头。

例如:

$ http GET http://127.0.0.1:8000/todos/ Origin:http://www.someorigin.com
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Date: Sat, 14 Nov 2015 04:42:38 GMT
Server: WSGIServer/0.1 Python/2.7.10
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN

您将通过预检 CORS 请求获得更多反馈:

$ http OPTIONS http://127.0.0.1:8000/todos/ Origin:http://www.someorigin.com
HTTP/1.0 200 OK
Access-Control-Allow-Headers: x-requested-with, content-type, accept, origin, authorization, x-csrftoken, user-agent, accept-encoding
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Date: Sat, 14 Nov 2015 04:45:37 GMT
Server: WSGIServer/0.1 Python/2.7.10
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN
于 2015-11-14T04:47:24.830 回答
9

尽管遵循了所有步骤,但不知何故django-cors-headers对我不起作用。Django 2飞行前检查将返回 405 错误。

我最终写了一个小中间件:

from django import http


class CorsMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        if (request.method == "OPTIONS"  and "HTTP_ACCESS_CONTROL_REQUEST_METHOD" in request.META):
            response = http.HttpResponse()
            response["Content-Length"] = "0"
            response["Access-Control-Max-Age"] = 86400
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Methods"] = "DELETE, GET, OPTIONS, PATCH, POST, PUT"
        response["Access-Control-Allow-Headers"] = "accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with"
        return response

然后在我的添加这个中间件settings.py

MIDDLEWARE = [
    'apps.core.middleware.CorsMiddleware',
     ... others below it
]

这对我有用。

于 2019-09-29T06:57:41.567 回答
6

我猜 corsheaders 和点击劫持中间件不兼容。至少我在注释掉时摆脱了 X-Frame-Options 标头 django.middleware.clickjacking.XFrameOptionsMiddleware

我刚CORS_ORIGIN_ALLOW_ALL = True设置。

于 2015-08-20T10:37:14.730 回答
4

我尝试安装django-cors-headers以修复使用生产设置运行 django 应用程序时遇到的错误。

来自源“http://localhost:3000”的“URL”已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。

CORS 错误

我的应用程序在开发和安装中运行时加载正常django-cors-headers并没有解决问题。Material出于某种原因,当我在生产中时,chrome 阻止了图标的加载。

在此处输入图像描述

一旦我发现问题是什么,我觉得分享我如何解决它很重要,因为我觉得很多人来这个问题都会有同样的情况。

该解决方案有望适用于那些从另一台服务器(如我之前的 AWS S3 存储桶)提供静态内容(如图像)并收到此错误的人。

如果你是并且它以同样的方式被 chrome 阻止,安装django-cors-headers将不会做任何事情。这是因为问题在于 S3 存储桶(Azure 等)的配置,而不是 django 应用程序。

转到 AWS S3 控制面板,选择用于托管 django 应用程序静态文件的存储桶后,单击权限选项卡。

s3 存储桶的权限选项卡

向下滚动到该cross-origin resource sharing (CORS)部分,然后单击“编辑”。

CORS 部分

如果您只想完全解决问题(仅提供被 chrome 阻止的静态文件),请输入以下 JSON,然后单击底部的“保存更改”。

[
    {
        "AllowedHeaders": [],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

这里有更多关于如何配置 S3 存储桶的 CORS 配置的信息。



保存此配置后,错误消失并且我的图标正确加载。

图标加载正确

脚注:

鉴于我也误解了Access-Control-Allow-Origin标题的工作原理,我从 Mozilla 的跨域资源共享文档中获取了一张图片,但对其进行了编辑以显示我的情况,希望能解释标题的工作原理。

服务器客户端图

想象一下,Chrome 和 localhost 正在交换邮件,突然间 chrome 开始从 AWS 接收邮件,但它没有 Chrome 的名称。好家伙 Chrome 在想,嗯,我不知道我是否应该查看此信息,它不是来自源 (localhost),所以我不知道我是否被允许,它可能是错误发送的敏感信息. 所以我不会打开它。

Allow-Access-Control-Origin 标头是 S3 写在该邮件上“没关系,您(Chrome)有权查看此邮件中的信息”。

django-cors-headers如果您有一个托管在服务器 A(源)上的应用程序正在向服务器 B 上的 django 应用程序发出请求,那么这种情况是必要的,这不是源。例如,如果您的 django 应用程序是托管在 heroku 上的 rest api,并且您在 Azure 上托管了一个向该 api 发出请求的 react/angular 应用程序 - 那么您的 django 应用程序将需要它。

需要 django-cors-headers 的 django 应用程序

于 2021-02-04T02:34:41.323 回答
3

我花了几个小时尝试了很多解决方案来解决这个问题。我认为我们需要遵循此处提到的步骤

再一步:最后在我添加后它起作用了:

CORS_ALLOW_HEADERS = ['*']

后:

ALLOWED_HOSTS=['*']

CORS_ORIGIN_ALLOW_ALL = 真

我认为它允许所有标题,包括授权。

于 2021-04-27T03:11:28.113 回答
2

从 Django 2 MIDDLEWARE_CLASSES 更改为 MIDDLEWARE。在这种情况下,如果您有 Django 2,请确保 MIDDLWARE 是应该的,以便 MIDDLEWARES 被执行。

于 2018-05-31T14:29:32.927 回答
1

最终解决方案是发送带有 CORS 允许标头的响应。

response["Access-Control-Allow-Origin"] = "*"
response['Content-Type'] = "application/json; charset=utf-8"
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "GET, OPTIONS"
response["Access-Control-Max-Age"] = "1000"
response["Access-Control-Allow-Headers"] = "X-Requested-With, Content-Type, My-Token"
于 2019-08-20T07:00:04.203 回答
1

对我来说,我不得不添加非标准标题。即使CORS_ORIGIN_ALLOW_ALL = True设置了,它仍然会检查是否允许标题。

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = list(default_headers) + [
    'my-custom-header',  
]

对于非标准方法也可以这样做:

from corsheaders.defaults import default_methods

CORS_ALLOW_METHODS = list(default_methods) + [
    'POKE',
]
于 2020-11-16T15:16:45.990 回答
0

如果上述设置(在 CORS 安装和更改中的配置后settings.py)均无效,则只需关闭您的广告拦截器(如果为您的本地网站启用)。这个小配置对我有用。

于 2022-01-13T00:12:25.120 回答
0

我在中间件数组的顶部添加了“corsheaders.middleware.CorsMiddleware”,它对我有用。

于 2021-09-11T03:43:34.493 回答
0

您是否尝试在 中使用 url iframe

如果是这种情况,那么标头X-Frame-Options: SAMEORIGIN可能会导致问题。

要修复它,请删除中间件,django.middleware.clickjacking.XFrameOptionsMiddleware.

于 2020-07-20T10:49:09.910 回答
0

django-cors-headers非常适合处理 CORS 策略问题。

完成上述步骤后,只需尝试清除浏览器缓存或尝试在 chrome(incognito) 或 firefox(private window) 中发出相同的请求。

于 2020-04-10T07:00:20.400 回答
-2

这对我有用:

python -m pip install django-cors-headers
MIDDLEWARE = [  
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]

`ALLOWED_HOSTS = ['*']`

`CORS_ORIGIN_ALLOW_ALL = True`

确保包括:corsheaders.middleware.CorsMiddleware,尽可能高

供参考:https ://pypi.org/project/django-cors-headers/,https : //docs.djangoproject.com/en/3.0/ref/settings/

于 2020-05-27T22:37:37.930 回答
-2

我所做的是贬低它的版本django-cors-headers以使其正常工作。我从版本移动3.2.12.4.0. 您可以通过使用 pip 安装特定版本来做到这一点

pip install django-cors-headers==2.4.0
于 2020-07-01T21:55:13.273 回答