XmlHttpRequest错误:Access-Control-Allow-Origin不允许源null
我正在开发一个页面,通过jQuery的AJAX支持从Flickr和Panoramio中提取图片。
Flickr方面工作正常,但是当我尝试从Panoramio中$.get(url, callback)
,我看到在Chrome的控制台中的错误:
XMLHttpRequest无法加载http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150 。 Access-Control-Allow-Origin不允许Origin null。
如果我直接从浏览器查询这个URL,它工作正常。 这是怎么回事,我能解决这个问题吗? 我是否错误地编写了我的查询,或者这是Panoramio妨碍我所要做的事情吗?
谷歌没有出现任何有用的匹配的错误消息 。
编辑
以下是一些显示问题的示例代码:
$().ready(function () { var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150'; $.get(url, function (jsonp) { var processImages = function (data) { alert('ok'); }; eval(jsonp); }); });
您可以在线运行该示例 。
编辑2
感谢Darin对此的帮助。 上面的代码是错误的。 用这个代替:
$().ready(function () { var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&minx=-30&miny=0&maxx=0&maxy=150&callback=?'; $.get(url, function (data) { // can use 'data' in here... }); });
logging下来,据我所知,你有两个问题:
-
您没有将“jsonp”types说明符传递给
$.get
,因此它使用了普通的XMLHttpRequest。 但是,您的浏览器支持CORS(跨源资源共享),以允许跨域XMLHttpRequest,如果服务器确定它。 这就是Access-Control-Allow-Origin
标题出现的地方。 -
我相信你提到你是从一个文件:/ / URL中运行它。 CORS头有两种方式表示跨域XHR是可以的。 一个是发送
Access-Control-Allow-Origin: *
(如果你通过$.get
到达Flickr,它们一定是做的),而另一个是回显Origin
头部的内容。 但是,file://
URL会产生一个无法通过echo-back授权的nullOrigin
。
Darinbuild议使用$.getJSON
来解决第一个问题。 如果它看到子stringcallback=?
那么将请求types从默认的“json”更改为“jsonp”会有一些魔力callback=?
在URL中。
这解决了第二个问题,不再尝试从file://
URL执行CORS请求。
为了澄清其他人,这里是简单的故障排除说明:
- 如果您尝试使用JSONP,请确保以下情况之一:
- 您正在使用
$.get
并将dataType
设置为jsonp
。 - 你正在使用
$.getJSON
并包括callback=?
在URL中。
- 您正在使用
- 如果你想通过CORS做一个跨域的XMLHttpRequest …
- 确保你通过
http://
进行testing。 通过file://
运行的脚本对CORS的支持有限。 - 确保浏览器实际上支持CORS 。 (Opera和Internet Explorer晚会晚了)
- 确保你通过
你需要在你的被调用的脚本中添加一个HEADER,这就是我在PHP中必须做的事情:
header('Access-Control-Allow-Origin: *');
更多详细信息,请访问Cross domain AJAX ou services WEB (法文)。
对于一个简单的HTML项目:
cd project python -m SimpleHTTPServer 8000
然后浏览你的文件。
适用于Google Chrome v5.0.375.127(我收到警报):
$.get('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150', function(json) { alert(json.photos[1].photoUrl); });
另外我会build议你使用$.getJSON()
方法,而不是在IE8上工作(至less在我的机器上):
$.getJSON('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150', function(json) { alert(json.photos[1].photoUrl); });
你可以尝试从这里在线 。
更新:
现在你已经显示你的代码,我可以看到它的问题。 你有一个匿名函数和内联函数,但都将被称为processImages
。 这就是jQuery的JSONP支持的工作原理。 注意我如何定义callback=?
所以你可以使用匿名函数。 您可以在文档中阅读更多内容 。
另一句话是,你不应该打电话给eval。 传递给匿名函数的参数已经被jQueryparsing成JSON。
只要请求的服务器支持JSON数据格式,请使用JSONP(JSON填充)接口。 它允许你做外部的域名请求,而无需代理服务器或花哨的标题的东西。
我们通过http.conf
文件pipe理它(编辑然后重新启动HTTP服务):
<Directory "/home/the directory_where_your_serverside_pages_is"> Header set Access-Control-Allow-Origin "*" AllowOverride all Order allow,deny Allow from all </Directory>
在Header set Access-Control-Allow-Origin "*"
,你可以把一个精确的URL。
这是相同的起源策略 ,您必须使用JSON-P接口或运行在同一主机上的代理。
如果您正在进行本地testing或从file://
这样的file://
调用该文件,那么您需要禁用浏览器安全性。
在MAC上: open -a Google\ Chrome --args --disable-web-security
就我而言,相同的代码在Firefox上运行良好,但在Google Chrome上却不行。 Google Chrome的JavaScript控制台说:
XMLHttpRequest cannot load http://www.xyz.com/getZipInfo.php?zip=11234. Origin http://xyz.com is not allowed by Access-Control-Allow-Origin. Refused to get unsafe header "X-JSON"
我必须放弃Ajax URL的www部分,以便与原始url正确匹配,然后工作正常。
作为最后的说明, Mozilla的文档明确表示
上面的例子将失败,如果头被通配为: Access-Control-Allow-Origin:*。 由于Access-Control-Allow-Origin显式地提到了http://foo.example ,所以证书认知内容被返回到调用的web内容。
因此,使用“*”不是一个简单的做法。 根本不工作:)
并不是所有的服务器都支持jsonp。 它要求服务器在其结果中设置callback函数。 我使用这个从返回纯json但不支持jsonp的网站获得json响应:
function AjaxFeed(){ return $.ajax({ url: 'http://somesite.com/somejsonfile.php', data: {something: true}, dataType: 'jsonp', /* Very important */ contentType: 'application/json', }); } function GetData() { AjaxFeed() /* Everything worked okay. Hooray */ .done(function(data){ return data; }) /* Okay jQuery is stupid manually fix things */ .fail(function(jqXHR) { /* Build HTML and update */ var data = jQuery.parseJSON(jqXHR.responseText); return data; }); }
我使用Apache服务器,所以我使用了mod_proxy模块。 启用模块:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so
然后添加:
ProxyPass /your-proxy-url/ http://service-url:serviceport/
最后,将proxy-url传递给你的脚本。
我也在Chrome中遇到同样的错误(我没有testing其他浏览器)。 这是由于我在domain.com上进行导航,而不是www.domain.com。 有点奇怪,但我可以通过添加以下行到.htaccess来解决这个问题。 它将domain.comredirect到www.domain.com,问题解决了。 我是一个懒惰的网页访问者,所以我几乎从不inputwww,但显然在某些情况下,它是必需的。
RewriteEngine on RewriteCond %{HTTP_HOST} ^domain\.com$ [NC] RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
确保您使用的是最新版本的JQuery。 我们遇到了这个错误的JQuery 1.10.2和错误得到解决后,使用JQuery 1.11.1
伙计们,
我遇到了类似的问题。 但是使用小提琴手,我能够解决这个问题。 问题是,在Web API一侧的CORS实现中configuration的客户端URL不能有尾随的正斜杠。 通过Google Chrome提交请求并检查Fiddler的Headers部分的TextView选项卡后,错误消息将如下所示:
*“指定的策略来源your_client_url:/”无效,不能以正斜杠结尾。
这真的很古怪,因为它在Internet Explorer上没有任何问题,但在使用Google Chrome进行testing时让我头疼。
我删除了CORS代码中的正斜杠,并重新编译了Web API,现在可以通过Chrome和Internet Explorer访问API,没有任何问题。 请给这个镜头。
谢谢,安迪
在这个链接发布的解决scheme有一个小问题,如果你改变一个文件,你将不得不重新启动服务器,以实际使用更新的文件(至less,在我的情况)。
所以search一下,我发现这一个使用:
sudo npm -g install simple-http-server # to install nserver # to use
然后它将在http://localhost:8000
。