Django 应用程序中的访问控制允许来源

问题描述 投票:0回答:6

我正在为基于 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);
            });
    });
}
python ajax django cordova cors
6个回答
114
投票

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
然后在中间件或视图中对请求进行任何过滤。


33
投票

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

@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

14
投票

您可以使用“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',
    ]

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


8
投票

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

要在项目中使用 django-cors-headers,请按照 cors headers 项目的 READMESetupConfiguration 部分中的指南进行操作,或者阅读下面的内容(为了方便起见,我从 README 中复制了).


设置

从 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
之前。


配置

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

`CORS_ALLOWED_ORIGINS`
`CORS_ALLOWED_ORIGIN_REGEXES`
`CORS_ALLOW_ALL_ORIGINS`

CORS_ALLOWED_ORIGINS

有权发出跨站点 HTTP 请求的源列表。默认为

[]

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

特殊值 null 由浏览器在“隐私敏感上下文”中发送,例如当客户端从 file:// 域运行时。根据

此错误,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 请求的源匹配的正则表达式的字符串列表。默认为 
[]

。当

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_ORIGINS

CORS_ALLOWED_ORIGIN_REGEXES
 来限制允许的来源列表。
以前此设置称为 
CORS_ORIGIN_ALLOW_ALL

,它仍然用作别名,新名称优先。


在我的例子中,我发布了一个超过 1 mb 的文件,并且由于

1
投票
配置(默认最大大小 1 mb)而收到此错误,所以......

对我来说
nginx.conf

的道路是

/etc/nginx/nginx.conf

就我而言,我只是在 
client_max_body_size

中添加了

http block

,它对我有用
http {
    ...
    client_max_body_size 200M;
}    

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

我想在这里添加文档:

0
投票

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

从此链接

https://github.com/adamchainz/django-cors-headers

如果你的 cors 中间件不是 django 中间件列表的顶部,上面的答案可能不起作用

© www.soinside.com 2019 - 2024. All rights reserved.