我正试图在客户端和apache服务的python(django)服务器上使用jQuery(1.7.1)支持的ajax来设置简单的跨源资源共享。根据我阅读的所有说明,我的标题设置正确,但我一直得到以下错误:
XMLHttpRequest无法加载http://myexternaldomain.com/get_data.起源http://localhost:8080不允许访问控制允许来源。
我试图发送的标题(我不确定它是否通过了浏览器)是:
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
javascript代码是
var request = $.ajax({
url : "http://myexternaldomain.com/get_data",
type : "POST",
dataType : "json",
crossDomain : true
});
请注意,origin
设置正确。服务器使用以下python代码添加标头Access-Control-Allow-Origin = *
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
如果我直接访问地址,它似乎可以确认标题设置正确
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
然而,在跨域设置中,它总是失败(同时尝试了chrome和firefox)。我试着按照这个问题的选定答案来实现代码,但得到了相同的错误
更新
我确信问题出在服务器端,因为我已经设法让ajax调用与另一个启用了CORS的公共服务器一起工作。当我比较从这个公共服务器返回的头和从我的返回的头时(当我从同一域测试时),我看不到任何可以解释差异的主要差异(见下文)。
我排除了一个微妙之处,这可能很重要,因为实际的域是一个由多个子域组成的amazon域。实际地址是http://ec2-23-20-27-108.compute-1.amazonaws.com/get_orders,可以随意探究一下,看看我做错了什么。
从公用服务器
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
从我的服务器-(不能跨域工作)
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
因此,我在访问URL时被响应误导了,事实上,问题是在执行ajax请求时,由于csrf保护,我收到了403(仅在firefox中显示,而不是chrome)错误。
您必须实现"预先飞行"的请求和响应,因为您的情况属于"不那么简单"的请求。只需要Origin标头的基本CORS只能具有"application/x-www-form-urlencoded"、"multipart/form-data"one_answers"text/plain"的内容类型。由于您返回了"application/json",因此无法满足此要求。
我对Django一无所知,但我发现通过使用Tomcat过滤器,在应用程序之外实现CORS支持更容易。看起来你可以用Django做同样的事情。
2013-08-11:看起来GitHub回购已经不在我们身边了。但Django包看起来仍然可以在https://pypi.python.org/pypi/django-cors/0.1
我使用了出色的django-cors头库,也遇到了这个问题。对我来说,解决方案是将"accept encoding"添加到默认的CORS_ALLOW_HEADERS元组中。