【问题标题】:django-cors-headers not workdjango-cors-headers 不起作用
【发布时间】:2015-03-18 17:52:40
【问题描述】:

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

【问题讨论】:

  • 你怎么说 CORS 标头不起作用?你能解释一下吗?
  • 大约 500 个错误发生在 CORS 中间件之前,因此它没有机会添加 CORS 标头。如果响应状态码是 500,这可能是问题所在,CORS 可能工作正常。

标签: python django django-cors-headers


【解决方案1】:

根据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

【讨论】:

  • 我应该在哪里添加这个响应?
【解决方案2】:

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

【讨论】:

  • 清除浏览器缓存也对我有用!
【解决方案3】:

别忘了添加

'corsheaders.middleware.CorsMiddleware',

在中间件变量的顶部:

查看文档:

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

【讨论】:

  • 这非常重要。我在 corsmiddleware 之前声明了一些其他中间件,但它默默地失败了。
【解决方案4】:

如果您要对此进行测试,您需要确保在请求中至少包含 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

【讨论】:

    【解决方案5】:

    尽管遵循了所有步骤,但不知何故 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
    ]
    

    这对我有用。

    【讨论】:

    • django-cors-headers 是垃圾。我只是想为所有请求启用 ACAO,花了半个小时来强制它工作,它开始在本地工作,但在 prod 中的基本身份验证下,或者由于其他原因,它什么也不做,安静地什么也不做。开发人员过于复杂了。在为这个代码提供优惠券时,我花了 1 分钟,它在任何地方都能完美运行。
    • 这对我有用,我关注了this middleware tutorial
    • django-cors-headers 对我来说总是有问题,但确实如此。谢谢!
    【解决方案6】:

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

    我刚刚设置了CORS_ORIGIN_ALLOW_ALL = True

    【讨论】:

    • 是的! CORS_ORIGIN_ALLOW_ALL = True 添加到 settings.py 它非常适合我,适合我的本地开发。
    【解决方案7】:

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

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

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

    一旦我发现问题所在,我觉得分享我如何解决它很重要,因为我觉得很多人遇到这个问题都会遇到同样的情况。

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

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

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

    向下滚动到cross-origin resource sharing (CORS) 部分并点击“编辑”。

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

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

    关于如何配置 S3 存储桶的 CORS 配置的更多信息 here



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

    脚注:

    鉴于我也误解了 Access-Control-Allow-Origin 标头的工作原理,我从 Mozilla 的文档中的Cross-Origin Resource Sharing 上拍摄了一张图像,但对其进行了编辑以显示我的情况,希望能解释标头的工作原理。

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

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

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

    【讨论】:

    • 非常感谢,它解决了我的问题和麻烦。非常感谢分享。
    【解决方案8】:

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

    还有一步: 我添加后终于可以使用了:

    CORS_ALLOW_HEADERS = ['*']

    之后:

    ALLOWED_HOSTS=['*']

    CORS_ORIGIN_ALLOW_ALL = 真

    我认为它允许包括授权在内的所有标头。

    【讨论】:

      【解决方案9】:

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

      【讨论】:

        【解决方案10】:

        最终解决方案是发送带有 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"
        

        【讨论】:

          【解决方案11】:

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

          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',
          ]
          

          【讨论】:

            【解决方案12】:

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

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

            【讨论】:

            • 清除浏览器缓存对我有用!
            【解决方案13】:

            您是否尝试使用iframe 中的网址?

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

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

            【讨论】:

              【解决方案14】:

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

              【讨论】:

                【解决方案15】:

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

                【讨论】:

                  【解决方案16】:

                  这对我有用:

                  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/

                  【讨论】:

                    【解决方案17】:

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

                    pip install django-cors-headers==2.4.0
                    

                    【讨论】:

                      猜你喜欢
                      • 2018-08-21
                      • 2016-06-08
                      • 2017-08-11
                      • 2016-11-16
                      • 2018-06-23
                      • 2019-08-12
                      • 2018-04-24
                      • 2018-01-16
                      • 2020-01-08
                      相关资源
                      最近更新 更多