2016-07-04 145 views
1

我正在开发一些与django网站aaa.com,它发送跨域ajax“GET”请求从bbb.com接收json数据,它也在django上运行,并且使用REST框架。在这一点上,一切工作都很好,加入crossDomain: true; withCredentials:true。当然,它可以在aaa.com的服务器端进行配置。
...-Allow-Credentials: true; ...-Allow-Origin: bbb.com跨域ajax选项错误403(Django)

主要问题出现在aaa.com试图使PUT POST DELETE ajax请求时。 根据CORS文档: [https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0],客户端AJAX请求是正确的,并
...-Allow-Headers, ...-Allow-Methods

...-Request-Headers, ...-Request-Methods

匹配,从而该请求不是“简单的”和第一全浏览器发送从预检请求aaa.com向bbb.com询问是否允许一些自定义标题和方法。

一切都还好但我仍然得到403错误。下面是请求/响应:

General: 
Request URL:http://bbb.com/api/someapipage/ 
Request Method:OPTIONS 
Status Code:403 Forbidden 
Remote Address:some ip:80 

Response Headers: 
Access-Control-Allow-Credentials:true 
Access-Control-Allow-Headers:accept, content-type, x-csrftoken, x-requested-with 
Access-Control-Allow-Methods:GET, POST, OPTIONS, HEAD, PUT, DELETE 
Access-Control-Allow-Origin:http://aaa.com 
Allow:GET, POST, HEAD, OPTIONS 
Connection:Keep-Alive 
Content-Language:en 
Content-Type:application/json 
Date:Mon, 04 Jul 2016 14:20:38 GMT 
Keep-Alive:timeout=5, max=100 
Server:gunicorn/19.6.0 
Transfer-Encoding:chunked 
Vary:Accept,Accept-Language,Cookie 
X-Frame-Options:SAMEORIGIN 

Request Headers: 
Accept:*/* 
Accept-Encoding:gzip, deflate, sdch 
Accept-Language:en-US,en;q=0.8,ru;q=0.6 
Access-Control-Request-Headers:accept, content-type, x-csrftoken 
Access-Control-Request-Method:POST 
Connection:keep-alive 
Host:aaa.com 
Origin:http://aaa.com 
Referer:http://aaa.com/ 
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36 

试图解决这个问题,一周后,我意识到,服务器要因人而异:对预排期的请求,饼干,因为跨域飞行前请求不能包含饼干这是不可能的在其标题中。

我开始找到了一些解决这个问题,并发现: https://code.djangoproject.com/ticket/13217

“启用django.middleware.locale.LocaleMiddleware导致该Django的增加了一个‘有所不同:饼干’。头到每个效应初探” 因此,localMiddleware添加头Vary:即使在飞行前选项响应

有很多推荐使用djang-cors-header来解决这些问题。但是使用这个包函数等于我在服务器端的设置。

我也发现漂亮包:django-dont-vary-on如果安装了可以设置装饰者关闭Vary:cookie,但在我的情况下,我需要关闭Vary:cookie只在OPTIONS响应中。

我对django有点新鲜感,实际上甚至无法想象在这种情况下该做什么。我的每一步就像走在矿场上一样。 有没有解决方案或一些替代方案?

回答

1

您必须将您的客户端的CORS白名单访问服务器。

如果他们是跨域请求,如果使用除GET,HEAD或POST以外的方法,则该请求将变为预检。

此外,如果POST用于与内容类型发送请求数据以外的 比应用程序/ x-WWW窗体-urlencoded,多部分/形式数据,或者 文本/无格式,它成为预检。

它的服务器允许处理或拒绝跨域客户端请求(默认)。

因此,如果您有权访问服务器端应用程序,则可以执行以下操作获取响应。

在服务器端

在你的服务器端和白名单您的客户端域或IP(这也是特定端口的)

pip install django-cors-headers 

在settings.py安装django-cors-headers,在你的INSTALLED_APPS添加它

INSTALLED_APPS = (
... 
    'corsheaders', 
... 
) 

添加corsheaders.middleware.CorsMiddleware在MIDDLEWARE_CLASSES

MIDDLEWARE_CLASSES = (
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    '**corsheaders.middleware.CorsMiddleware**', 
    'django.middleware.common.CommonMiddleware', 
.... 
) 

,并定义白名单CORS

CORS_ORIGIN_WHITELIST = (
    'aaa.com', 
) 

现在,当您在CORS白名单添加你的客户,你现在可以做一个成功的Ajax请求。

+0

感谢您的回复!只要我获得访问服务器端,我会尝试你的解决方案 –

+0

这解决了我的问题!非常感谢! –

+0

我很高兴它帮助:-) – kapilsdv