首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跨域ajax选项错误403 (Django)

跨域ajax选项错误403 (Django)
EN

Stack Overflow用户
提问于 2016-07-04 14:42:56
回答 1查看 2.9K关注 0票数 2

我正在使用django开发一些站点aaa.com,它发送跨域ajax "GET“请求,以便从运行在django上并使用REST框架的bbb.com接收json数据。在这一点上,添加crossDomain: true; withCredentials:true一切都很好。当然,它配置在aaa.com的服务器端。

...-Allow-Credentials: true; ...-Allow-Origin: bbb.com

当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个错误。以下是请求/答复:

代码语言:javascript
复制
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

经过一周的尝试来解决这个问题,我意识到服务器想要改变:在预先打开的请求上使用Cookie,这是不可能的,因为跨域的飞行前请求不能在其标题中包含cookie。

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

“启用django.middleware.locale.LocaleMiddleware会使django向每个响应添加一个'Vary: Cookie‘头。”因此,localMiddleware添加了头部变化: Cookie,甚至在飞行前选项响应中。

有许多建议使用djang-cors-header来解决其中的一些问题。但是使用这个包函数等于我在服务器端的设置。

我还发现了漂亮的包:django-dont-vary-on,如果安装了它,可以将装饰器设置为关闭Vary:cookie,但在我的示例中,我只需要在选项响应中关闭Vary:cookie。

我对django有点陌生,甚至无法想象在这种情况下该怎么做。我的每一步都像走在矿场上。有什么解决办法或其他办法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-04 15:55:45

你必须用白名单显示你的客户来访问服务器。

如果它们是跨域请求,如果您使用的是GET、HEAD或POST以外的方法,则请求就会提前完成。

此外,如果POST用于发送内容类型而不是application/x-www-form-urlencoded、多部分/表单-数据或文本/纯文本的请求数据,则它会变得预先设置。

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

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

在服务器端

在服务器端安装django-cors-标头,并列出客户端域或IP (也是特定端口)。

代码语言:javascript
复制
pip install django-cors-headers

在settings.py中,将它添加到您的INSTALLED_APPS中

代码语言:javascript
复制
INSTALLED_APPS = (
...
    'corsheaders',
...
)

在corsheaders.middleware.CorsMiddleware中添加MIDDLEWARE_CLASSES

代码语言:javascript
复制
MIDDLEWARE_CLASSES = (
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    '**corsheaders.middleware.CorsMiddleware**',
    'django.middleware.common.CommonMiddleware',
....
)

定义一个CORS白名单

代码语言:javascript
复制
CORS_ORIGIN_WHITELIST = (
    'aaa.com',
)

现在,当您将客户端添加到CORS白名单中时,现在您将能够成功地发出ajax请求。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38187340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档