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下来,据我所知,你有两个问题:

  1. 您没有将“jsonp”types说明符传递给$.get ,因此它使用了普通的XMLHttpRequest。 但是,您的浏览器支持CORS(跨源资源共享),以允许跨域XMLHttpRequest,如果服务器确定它。 这就是Access-Control-Allow-Origin标题出现的地方。

  2. 我相信你提到你是从一个文件:/ / URL中运行它。 CORS头有两种方式表示跨域XHR是可以的。 一个是发送Access-Control-Allow-Origin: * (如果你通过$.get到达Flickr,它们一定是做的),而另一个是回显Origin头部的内容。 但是, file:// URL会产生一个无法通过echo-back授权的null Origin

Darinbuild议使用$.getJSON来解决第一个问题。 如果它看到子stringcallback=?那么将请求types从默认的“json”更改为“jsonp”会有一些魔力callback=? 在URL中。

这解决了第二个问题,不再尝试从file:// URL执行CORS请求。

为了澄清其他人,这里是简单的故障排除说明:

  1. 如果您尝试使用JSONP,请确保以下情况之一:
    • 您正在使用$.get并将dataType设置为jsonp
    • 你正在使用$.getJSON并包括callback=? 在URL中。
  2. 如果你想通过CORS做一个跨域的XMLHttpRequest …
    1. 确保你通过http://进行testing。 通过file://运行的脚本对CORS的支持有限。
    2. 确保浏览器实际上支持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