使用 Django 和 Angular 的 CORS 预检请求

Posted

技术标签:

【中文标题】使用 Django 和 Angular 的 CORS 预检请求【英文标题】:CORS preflight request with Django and Angular 【发布时间】:2016-09-19 05:45:44 【问题描述】:

我试图向 REST api 发出请求。这是一个 CORS 请求。 我的前端:Angular 1.5 (localhost:3000) 我的后端:Django (*****.ddns.net)

所以我正在使用一项服务(由不想共享代码的人制作:(),即在实际请求(预检)之前执行 OPTIONS 请求。准确地说,调用是通过解决 UI 路由器状态定义的选项。 Django 有 CORS 允许 *.

这是我在谷歌浏览器中遇到的错误:

XMLHttpRequest cannot load https://****.net/api/myprofile. The request was redirected to 'https://*****.net/punchclock/api/myprofile/', which is disallowed for cross-origin requests that require preflight.

如果我在控制器中执行经典的 $http 请求,它就可以工作。

这是我的 django 收到的请求:

+6655:5740d0f9:10|
OPTIONS /punchclock/api//myprofile HTTP/1.0|
Host:*****.net|
Connection:close|
Pragma:no-cache|
Cache-Control:no-cache|
Access-Control-Request-Method:GET|
Origin:http%3a//localhost%3a3000|
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/50.0.2661.102 Safari/537.36|
Access-Control-Request-Headers:accept, authorization|
Accept:*/*|
Referer:http%3a//localhost%3a3000/dashboard|
Accept-Encoding:gzip, deflate, sdch|
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,es;q=0.2
-6655:5740d0f9:10

如果我与邮递员合作,这是我得到的响应(当我执行 OPTIONS 请求时,它正在与邮递员合作)

Access-Control-Allow-Headers →x-requested-with, content-type, accept, origin, authorization, x-csrftoken
Access-Control-Allow-Methods →GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin →*
Access-Control-Max-Age →86400
Allow →GET, HEAD, OPTIONS
Connection →keep-alive
Content-Type →application/json
Date →Sat, 21 May 2016 21:15:02 GMT
Server →nginx/1.6.2
Transfer-Encoding →chunked
Vary →Accept
X-Frame-Options →SAMEORIGIN

我认为这是 Django 方面的问题,我不知道。如果您有任何想法...(我需要了解很多关于 CORS 的知识...)

【问题讨论】:

【参考方案1】:

确保您定位的 URL 结构正确,并且在您调用的路由末尾有一个斜杠。正如提到的here。所以不是这个

'http://localhost:5000/auth'

你会这样称呼

'http://localhost:5000/auth/'

希望这会有所帮助。

【讨论】:

【参考方案2】:

这可能是因为您发送的某些标头是不允许的。为了确保,只需转到 google chrome 调试器并复制请求标头并使用邮递员发送它们。如果失败,请删除标题,直到找出不允许的标题。

有一个similar answer here 可能会有所帮助。具体在哪里说

根据W3 CORS Spec Section 6.2 Preflight Requests,如果提交的任何标头与允许的标头不匹配,预检必须拒绝请求。

【讨论】:

我照你说的做了。首先,我检查了 chrome 调试器,这就是我得到的:The first request, the OPTIONS one returns a 200 Request Method:OPTIONS Status Code:200 OK Remote Address: **.***.***.***:*** 但第二个:Request URL:https://*****.ddns.net/api/myprofile Request Method:GET Status Code:301 Moved Permanently Remote Address:**.***.***.***:*** 我还尝试使用邮递员(+拦截器插件)添加所有标头,它也返回 200。 如果您从 OPTIONS 获得 200,那么您的问题不是 CORS,我认为实际请求中的 301 是重定向,因此服务器端的人应该能够在那里为您提供帮助。或者当您获得重定向时向新网址发出第二次请求 我尝试使用所有标题并模拟邮递员的获取,它是200...我很困惑。而且我还尝试直接在重定向的 url 上执行 OPTIONS 和 GET,我也遇到了同样的问题。 更新:我发现了一个关于重定向的问题,如果我直接通过我的 Angular 应用程序调用 api,它现在正在工作,所以问题是请求中有重定向。根据另一位post 的说法,该问题可能与此修订有关。我会调查的。谢谢@inkalimeva

以上是关于使用 Django 和 Angular 的 CORS 预检请求的主要内容,如果未能解决你的问题,请参考以下文章

原生 ios phonegap/cordova 的 Angular $templateCache 和 $stateProvider 修复

合并 Angular 和 Django 的 url

在 Angular6 前端使用 Django 通道

如何使用 django rest 框架和 angular 上传图片?

Angular中的核心模块组件和共享模块实现

angular.js 中的 Django formset 等效项