javascript 尽管标头正确,但 CORS Access-Control-Allow-Origin
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9613210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CORS Access-Control-Allow-Origin despite correct headers
提问by zenna
I am trying to set up simple Cross-Origin Resource Sharing using jQuery (1.7.1) powered ajax on the client and apache served python (django) server. According to all the instructions I have read my headers are set correctly, but I keep getting the following error:
我正在尝试使用 jQuery (1.7.1) 驱动的 ajax 在客户端和 apache 服务的 python (django) 服务器上设置简单的跨域资源共享。根据我阅读的所有说明,我的标题设置正确,但我不断收到以下错误:
XMLHttpRequest cannot load http://myexternaldomain.com/get_data. Origin http://localhost:8080is not allowed by Access-Control-Allow-Origin.
XMLHttpRequest 无法加载http://myexternaldomain.com/get_data。Access-Control-Allow-Origin 不允许Origin http://localhost:8080。
The header being I am trying to (I am not sure it is even getting past the browser) send is:
我正在尝试发送的标题(我不确定它是否已经通过浏览器)发送是:
Request URL:http://myexternaldomain.com/get_data
Accept:application/json, text/javascript, */*; q=0.01
Origin:http://localhost:8080
Referer:http://localhost:8080/static/js/test-zetta.html
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11
The javascript code is
javascript代码是
var request = $.ajax({
url : "http://myexternaldomain.com/get_data",
type : "POST",
dataType : "json",
crossDomain : true
});
Note that origin
is set correctly. The server adds the header Access-Control-Allow-Origin = *
using the following python code
注意origin
设置正确。服务器Access-Control-Allow-Origin = *
使用以下python代码添加标头
def process_response(self, response):
if response.has_header('Access-Control-Allow-Origin'):
return response
response['Access-Control-Allow-Origin'] = '*'
return response
def get_orders(request):
""" Tell worker what to do """
response_data = {}
response_data['action'] = 'probe'
response = process_response(HttpResponse(json.dumps(response_data), mimetype="application/json"))
return response
If I visit the address directly, it appears to confirm that the header is being set correctly
如果我直接访问地址,似乎是确认header设置正确
Access-Control-Allow-Origin:*
Content-Type:application/json
Date:Thu, 08 Mar 2012 05:06:25 GMT
Server:Apache/2.2.20 (Ubuntu)
Transfer-Encoding:chunked
However in the cross domain setting it always fails (tried both chrome and firefox). I've tried implementing the code exactly as per the selected answer to thisquestion, but get the same error
但是在跨域设置中它总是失败(尝试了 chrome 和 firefox)。我已经尝试完全按照此问题的所选答案来实现代码,但得到相同的错误
Update
更新
I am quite sure that the problem is server side, as I have managed to get my ajax calls working with a different public CORS enabled server. When I compare the headers coming back from this public server, and the ones returned from mine (when I test from same domain), I cannot see any major difference which could account for difference (see below).
我很确定问题出在服务器端,因为我已经设法让我的 ajax 调用与不同的公共 CORS 启用服务器一起工作。当我比较从这个公共服务器返回的标头和从我的返回的标头(当我从同一域测试时)时,我看不到任何可能导致差异的主要差异(见下文)。
One subtlety that I excluded, which may or may be important is that the actual domain is an amazon domain of multiple subdomains. The real addressis http://ec2-23-20-27-108.compute-1.amazonaws.com/get_orders, feel free to probe it to see what I am doing wrong.
我排除了一个可能或可能很重要的微妙之处,即实际域是多个子域的亚马逊域。的真实地址是http://ec2-23-20-27-108.compute-1.amazonaws.com/get_orders,随时探测它,看看有什么我做错了。
From Public server
从公共服务器
Access-Control-Allow-Origin:*
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:622
Content-Type:text/html
Date:Thu, 08 Mar 2012 15:33:20 GMT
Keep-Alive:timeout=15, max=99
Server:Apache/2.2.14 (Ubuntu)
Vary:Accept-Encoding
X-Powered-By:Perl/5.8.7, PHP/4.4.0
From my server - (not working cross domain)
从我的服务器 - (不工作跨域)
Access-Control-Allow-Origin:*
Content-Encoding:gzip
Content-Type:text/plain
Date:Thu, 08 Mar 2012 15:32:24 GMT
Server:Apache/2.2.20 (Ubuntu)
Transfer-Encoding:chunked
Vary:Accept-Encoding
采纳答案by zenna
So I was being mislead by the response from going to the URL, and in fact the problem was that when doing the ajax request, I was getting a 403 (only revealed in firefox not chrome) error due to csrf protection.
所以我被转到 URL 的响应误导了,实际上问题是在执行 ajax 请求时,由于 csrf 保护,我收到了 403(仅在 firefox 而非 chrome 中显示)错误。
回答by James Sumners
You have to implement a "pre-flighted" request and response because your situation counts as a "not so simple" request. Basic CORS, that only requires the Origin header, can only have content types of "application/x-www-form-urlencoded", "multipart/form-data", and "text/plain". Since you return "application/json", you don't meet this requirement.
您必须实施“预先飞行”的请求和响应,因为您的情况算作“不那么简单”的请求。仅需要 Origin 标头的基本 CORS 只能具有“application/x-www-form-urlencoded”、“multipart/form-data”和“text/plain”的内容类型。由于您返回“application/json”,因此您不符合此要求。
I don't know anything about Django, but I found it easier to implement CORS support outside of my application through the use of a Tomcat filter. It looks like you can do the same thingwith Django.
我对 Django 一无所知,但我发现通过使用Tomcat filter在我的应用程序之外实现 CORS 支持更容易。看起来你可以用 Django做同样的事情。
2013-08-11:It looks like the GitHub repo is no longer with us. But the Django package looks to still be available at https://pypi.python.org/pypi/django-cors/0.1
2013-08-11:看起来 GitHub 存储库不再与我们在一起。但是 Django 包看起来仍然可以在https://pypi.python.org/pypi/django-cors/0.1 获得
回答by rattray
I was using the excellent django-cors-headerslibrary and ran into this problem as well. For me, the solution was to add 'accept-encoding' to the default CORS_ALLOW_HEADERS tuple.
我正在使用优秀的django-cors-headers库,也遇到了这个问题。对我来说,解决方案是将“接受编码”添加到默认的 CORS_ALLOW_HEADERS 元组中。