【问题标题】:Access-Control-Allow-Origin in Django appDjango 应用程序中的访问控制允许来源
【发布时间】:2014-04-16 19:47:42
【问题描述】:

我正在为基于 Django 的应用程序开发 Phonegap 应用程序,但在尝试进行 Ajax 调用时出现此错误:

XMLHttpRequest cannot load http://domain.herokuapp.com/getcsrf/?tags=jquery%2Cjavascript&tagmode=any&format=json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. 

我怎样才能让我的 Django 应用程序允许某些 url 跨源?

这是我的 Ajax 代码:

get: function() {
    $.getJSON("http://domain.herokuapp.com/getcsrf/",
    {
        tags: "jquery,javascript",
        tagmode: "any",
        format: "json"
    },
    function(data) {
        $.each(data.items, function(item){
            console.log(item);
            });
    });
}

【问题讨论】:

  • 从未使用过 Django,但是您是否将服务器添加到您的 cordova/phonegap 白名单?
  • 你是怎么做到的?不知道您可以将服务器白名单添加到 cordova/phonegap 应用程序
  • 在我的 config.xml 我已经有默认的<access origin="*" />
  • 感谢@MBillau 的提示

标签: python ajax django cordova cors


【解决方案1】:

默认情况下,Django 不提供提供跨域所需的标头。最简单的方法是使用这个为您处理它的 Django 应用程序:https://github.com/adamchainz/django-cors-headers

  • 添加到已安装的应用程序
  • 添加到中间件
  • 然后像...
CORS_ALLOWED_ORIGINS = [
    "http://read.only.com",
    "http://change.allowed.com",
]

要支持全部允许,只需使用设置... CORS_ALLOW_ALL_ORIGINS = True 然后在中间件或视图中对请求进行任何过滤。

【讨论】:

  • 好的,已经安装了,但似乎没有改变,可能是因为我想允许 3 个 url(使用 django-cors-heades 的任何提示或最佳实践?)
  • 我更新了示例以展示如何将域/url 添加到白名单。
  • Cordova/Phonegaps 应用程序由 file:// 位置运行并且没有域,因此如何在 CORS_ORIGIN_WHITELIST =() 中列出它们?
  • 对于使用 Django 1.10 或更高版本的人,请使用:github.com/zestedesavoir/django-cors-middleware。原链接不支持1.10。
  • 设置已重命名为CORS_ALLOW_ALL_ORIGINS = True
【解决方案2】:

对于单个视图,您可以手动添加标题:

@require_GET
def api_getto(request):
    response = JsonResponse(
        # your stuff here
    )
    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"
    return response

【讨论】:

    【解决方案3】:

    您可以使用“django-cors-headers”。只需使用 pip 安装即可:

        pip install django-cors-headers
    

    将“corsheaders”添加到已安装的应用中:

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

    添加中间件:

        MIDDLEWARE = [
            ...,
            'corsheaders.middleware.CorsMiddleware',
            'django.middleware.common.CommonMiddleware',
            ...,
        ]
    

    然后将其添加到您的“settings.py”中:

        CORS_ALLOWED_ORIGINS = [
            'http://siteyouwantto.allow.com',
            'http://anothersite.allow.com',
        ]
    

    如果您还想允许某些域发出“POST”请求,请将其添加到您的“settings.py”中,并且不要忘记将其添加到“CORS_ALLOWED_ORIGINS”中。

        CSRF_TRUSTED_ORIGINS = [
            'http://siteyouwantto.allow.com',
        ]
    

    我希望这能解决您的问题:)

    【讨论】:

    • 您还需要在设置中添加 cors headers 应用程序和中间件,请参阅 the READMEmy answer
    • @orangecaterpillar 你是对的!我将编辑我的答案:)
    【解决方案4】:

    您可以按照其他人的建议使用 django-cors-headers,在撰写本文时,您需要遵循以下所有步骤。

    要在您的项目中使用 django-cors-headers,请按照 the cors headers project's READMESetupConfiguration 部分中的指南进行操作,或请在下面阅读(为方便起见,我从自述文件中复制了它)。


    SETUP

    从 pip 安装:

    python -m pip install django-cors-headers

    然后将其添加到您安装的应用程序中:

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

    确保添加尾随逗号,否则您可能会收到 ModuleNotFoundError(请参阅此博客文章)。

    您还需要添加一个中间件类来监听响应:

    MIDDLEWARE = [
        ...,
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        ...,
    ]
    

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

    另外,如果你使用的是CORS_REPLACE_HTTPS_REFERER,它应该放在Django的CsrfViewMiddleware之前。


    CONFIGURATION

    在您的 Django 设置中配置中间件的行为。您必须至少设置以下三个设置之一:

    `CORS_ALLOWED_ORIGINS`
    `CORS_ALLOWED_ORIGIN_REGEXES`
    `CORS_ALLOW_ALL_ORIGINS`
    

    CORS_ALLOWED_ORIGINS

    授权进行跨站点 HTTP 请求的源列表。默认为[]

    Origin 由the CORS RFC Section 3.2 定义为 URI 方案 + 主机名 + 端口,或特殊值“null”或“file://”之一。默认端口(HTTPS = 443,HTTP = 80)在这里是可选的。

    特殊值 null 由浏览器在"privacy-sensitive contexts" 中发送,例如当客户端从 file:// 域运行时。根据this bug,Android 上的某些版本的 Chrome 会意外发送特殊值 file://。

    例子:

    CORS_ALLOWED_ORIGINS = [
        "https://example.com",
        "https://sub.example.com",
        "http://localhost:8080",
        "http://127.0.0.1:9000"
    ]
    

    以前此设置称为CORS_ORIGIN_WHITELIST,它仍然作为别名使用,新名称优先。

    CORS_ALLOWED_ORIGIN_REGEXES

    代表正则表达式的字符串列表与授权进行跨站点 HTTP 请求的 Origin 匹配。默认为[]。当CORS_ALLOWED_ORIGINS 不切实际时很有用,例如当您有大量子域时。

    例子:

    CORS_ALLOWED_ORIGIN_REGEXES = [
        r"^https://\w+\.example\.com$",
    ]
    

    以前此设置称为CORS_ORIGIN_REGEX_WHITELIST,它仍然作为别名使用,新名称优先。

    CORS_ALLOW_ALL_ORIGINS

    如果True,将允许所有来源。其他限制允许来源的设置将被忽略。默认为False

    将此设置为True 可能很危险,因为它允许任何网站向您的网站发出跨域请求。通常,您需要使用 CORS_ALLOWED_ORIGINSCORS_ALLOWED_ORIGIN_REGEXES 限制允许的来源列表。

    以前此设置称为CORS_ORIGIN_ALLOW_ALL,它仍然作为别名使用,新名称优先。

    【讨论】:

    • 请注意,此子句中似乎有一个丢失/损坏的链接:“确保添加尾随逗号,否则您可能会收到 ModuleNotFoundError(请参阅此博客文章)。”
    【解决方案5】:

    在我的情况下,我发布了一个超过 1 mb 的文件,并且由于 nginx 配置(默认最大大小 1 mb)而出现此错误所以......

    对我来说nginx.conf 的路径是/etc/nginx/nginx.conf

    就我而言,我刚刚在http block 中添加了client_max_body_size,它对我有用

    http {
        ...
        client_max_body_size 200M;
    }    
    

    请务必在更改此配置后重新启动 nginx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-02
      • 2021-09-07
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 2018-12-04
      • 2017-12-28
      • 1970-01-01
      相关资源
      最近更新 更多