我正在开发一个通过jquery的Ajax支持从Flickr和Panoramio中提取图像的页面。
Flickr端工作正常,但当我尝试从Panoramio中删除cx1(0)时,我在Chrome的控制台中看到一个错误:
XMLHttpRequest cannot load 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. Origin null is not allowed by Access-Control-Allow-Origin.
如果我直接从浏览器查询该URL,它就可以正常工作。发生了什么事,我能避开吗?我是在错误地编写查询,还是Panoramio这样做妨碍了我的工作?
谷歌没有在错误信息中找到任何有用的匹配项。
编辑
下面是一些显示问题的示例代码:
1 2 3 4 5 6 7 8 9 10 11
| $().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
多亏了达林的帮助。上面的代码是错误的。改为使用:
1 2 3 4 5 6 7
| $().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...
});
}); |
- 您从哪个URL发出请求?例如,这不是一个动态生成的iframe,您将document.write放入其中?
- 您可以将来自请求的HTTP响应发布到每个服务吗?我敢打赌Panoramio没有提供访问控制允许来源。有关示例,请参见w3.org/tr/cors。
- @凯文,如果服务器发送JSONP,就不需要这些头。
- @Pekka,我正在运行本地机器的页面(file:///C:/)。不涉及iframe。
- @画出如果从HTTP URL运行它会发生什么?这样做不会有什么不同,只是为了排除这种可能性。
- @Pekka,我从jsiddle运行它,并有相同的问题(更新问题中的链接!)
- 有jsonp.jit.su,这是一个免费的json代理"允许跨域请求任何json api",它在github github.com/afeld/jsonp上。
据我所知,你有两个问题:
您没有将"jsonp"类型说明符传递给您的$.get,因此它使用了一个普通的xmlhttpRequest。但是,您的浏览器支持CORS(跨源站资源共享),允许跨域XMLHttpRequest(如果服务器终止)。这就是Access-Control-Allow-Origin的头条出现的地方。
我相信你提到过你是从一个文件中运行它的。CORS报头有两种方法来表示跨域XHR正常。一个是发送Access-Control-Allow-Origin: *(如果您通过$.get到达flickr,他们一定是这么做的),另一个是回送Origin头的内容。但是,file://URL生成的Origin为空,不能通过echo back进行授权。
第一个问题是通过达林建议使用$.getJSON迂回解决的。如果在URL中看到子字符串callback=?,那么将请求类型从默认的"json"更改为"jsonp"就有点神奇了。
这解决了第二个问题,不再尝试执行来自file://URL的CORS请求。
为了向其他人澄清,以下是简单的故障排除说明:
如果您尝试使用jsonp,请确保以下情况之一:
- 你用的是$.get,把dataType设为jsonp。
- 您使用的是$.getJSON,并在URL中包含callback=?。
如果您试图通过CORS执行跨域XMLHttpRequest…
确保您正在通过http://进行测试。通过file://运行的脚本对CORS的支持有限。
确保浏览器实际上支持CORS。(Opera和Internet Explorer来晚了)
- 那么解决这个问题的方法是什么呢?
- 回调=?FTW
- 一些浏览器,如chrome,如果以参数--allow file access from files开始,则允许cors
- 以东十一〔四〕不是为我工作,但以东十一〔八〕是为我工作。对此有什么解释吗?
- @Crunkchitis:我不知道为什么callback=?不适合您,因为当前的jQuery文档仍然认为它应该工作,但是如果我正确地阅读它们,它们也会说anything_else=?也可以工作。
- 谢谢。我使用了通用的$.ajax()函数,并将数据类型从json更改为jsonp有效。
- chrome允许从本地文件发出这种请求,只需使用--disable-web-security运行它即可。
- 我需要安装一个Web服务器来通过http://进行测试吗?或者有没有一种方法可以使用该协议简单地打开文件?
- @分形尝试在文件夹中运行带有文件的python -m SimpleHTTPServer,然后打开http://localhost:8000/。我的CORS工具倾向于使用django或bottle,它们有自己的开发服务器,但它可能会工作。(如果没有,而且你认识任何一条Python,那么用瓶子的hello world例子来适应就很简单了。)
- 对于记录,null是Origin的完全有效值,确实可以在Access-Control-Allow-Origin头中返回。(见Origin规范和CORS规范。)
- 从getJSON文档来看:这是一个简写的ajax函数,相当于:$.ajax({ dataType:"json", url: url, data: data, success: success });,我不知道它如何等同于$.get和dataType和jsonp的$.get,以及callback=?在这里能提供什么帮助…
- @在链接的页面上,它会说"如果URL包含字符串"callback=?。(或类似的,由服务器端API定义),请求被视为JSONP。更多详细信息,请参见$.ajax()中关于jsonp数据类型的讨论。"
- @凯文·克里斯托弗·亨利,我认为null的有效性没有问题。问题是,根据规范,浏览器显示null != null行为。
- ssokolow @:which规格?也许我错过的东西,但我似乎to that the spec out of the CORS的GOES that the Way to say the same路匹配算法applies:确切的说因为是"the above algorithm with nullwhen the also of an序列化函数的ASCII字符串是null is the origin"。
- @我知道kevinchristopherhenry这晚,我不有时间的情况下,现在唐track of the,but is that of the依据EN nullis used when the actual placeholder的起源是不知道muster安通,which does not to null序列化的起源,有平等的null出现echoed回来。这表明,在地方上的类型6454 7.3 of which is the RFC RFC,联为"ASCII文档序列化你referenced茶"。This is also to redirects应用行为等"6步steps of the"重定向"你7.1.7 of the document联。
- 引用:"你关注ssokolow the references when the origin null浏览器should to set the address;他们不安的问题是否Originrequest header of value of an Access-Control-Allow-Origin响应值匹配nullshould of when nullCORS在做检查。addressed that is by the section of the section的引用和4.9取标准清晰,which that they should做匹配。(我可以告诉你从我的个人经验给他们的课程,虽然不能证明of that for every浏览器。)
- "你看到的部分kevinchristopherhenry to which makes 2. If origin is null or failure, return failure.联说,因为完美的意识,如果它是可能的我们两在the pages for different to both序列化nullby the same to be authenticated非授权*CORS质量安全,它会好的孔。因此,当initially说,exhibiting null != null行为。
- ssokolow @:你读下一句吗?"注:'null'is not null。"that is,the value of the header absence失效,回车;其他包括when the value is the 'null'-连续字符串。当你给,there will be a check the CORS火柴和会通。there to be似乎不想多知道点你知道我会在这里leave this as a to其他预警。
- 11点kevinchristopherhenry accept that",因为我明白,现在的分配太多的重要性在capitalization to the the注释太小和缺乏to the of在第2步,向后的记号,但仍然不解释观察到的行为原则,茶和两位nullwhich产生平等会出现因为它起源或cannot笔在安全孔。我能承担别人的地方,只在包恩tells of the迷宫,browsers to the echoed出现反对UUID的FQDN / / nullthe used for local或敏感等。我们在他们Origin: nullsent to get to be translated。
您可能需要在调用的脚本中添加一个头部,下面是我在PHP中要做的:
1
| header('Access-Control-Allow-Origin: *'); |
有关跨域Ajax OU服务Web(法语)的更多详细信息。
- how is this done on a normal(没有PHP的HTML文件)?
- 你depends @:由HTTP服务器的URI。与Apache,你会想看一_ mod headers。
- HTTP的URI -半@<="等接入允许控制origin ="*">"内容
- 我herberthamaral @<head><本内增/头>,但它不工作对我来说。我想在Safari和Chrome还恩,but in the控制台,get the origin is not null模式接入允许控制允许误差来源。
- 它不工作在the head of the HTML文件为安全原因。EN has to be a header。stackoverflow.com /问题/ 7015782 / & hellip;
- 我不能在HTML页。EN has to be specified by the program that is the HTML页面发送你的网络浏览器(over the所谓Web服务器)。
对于简单的HTML项目:
1 2
| cd project
python -m SimpleHTTPServer 8000 |
然后浏览您的文件。
- 当你进入0.0.0.0:8000并尝试POST请求时,你会得到:code 501, message Unsupported method ('POST')的Google请求。
- "当一个python web服务器(例如cherrypy)说它在0.0.0.0上运行时,意味着它正在监听所有最终在该计算机上的TCP通信,不管请求的主机名或IP是什么。"所以,可以尝试向localhost发帖:8000 stackoverflow.com/a/4341808/102022。
- 我试过了,但还是犯了同样的错误。
在Google Chrome v5.0.375.127上为我工作(我收到警报):
1 2 3 4
| $.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);
}); |
另外,我建议您使用$.getJSON()方法,因为以前的方法不适用于IE8(至少在我的机器上):
1 2 3 4
| $.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=?,以便您可以使用匿名函数。您可以在文档中了解更多关于它的信息。
另一句话是你不应该叫埃瓦尔。传递给匿名函数的参数将被jquery解析为json。
- 好吧,让我再试一次。我在另一个版本的chrome btw"6.0.472.51测试版"。
- 你的代码对我有用。不过,我用一些代码更新了我的问题。
- 谢谢你给我的提示。我将您的jsFiddle示例分叉以显示问题(jsFiddle.net/zfvkm),现在看到错误消息xmlhttpRequest cannot load panoramio.com/wapi/data/…。访问控制allow origin不允许使用origin fiddle.jshell.net。
- @达林,谢谢你的更新。我明白你的意思,我已经尝试了一些组合,但是我还没有找到一种方法来访问返回的对象。您可以更新JSfiddle示例来显示访问数据吗?如果将回调设置为?,则返回的json被括号包围。您没有为回调函数定义参数,并且this的值似乎没有响应对象(至少,.data的值是null)。
- @Drew,更新的示例:jsfiddle.net/zfvkm/2以及我的帖子。
- @达林,太棒了。多谢。现在工作得很好。对于其他任何阅读本文的人,callback=?的包含命令jquery在内部生成随机函数名,从而调用传递给.getJSON的匿名函数。感激。
只要请求的服务器支持JSON数据格式,就使用JSONP(JSON填充)接口。它允许您在没有代理服务器或花哨的头文件的情况下进行外部域请求。
它是相同的源策略,您必须使用JSON-P接口或在同一主机上运行的代理。
如果您正在进行本地测试或从类似于file://的地方调用文件,那么您需要禁用浏览器安全性。
在Mac上:open -a Google\ Chrome --args --disable-web-security
我们通过http.conf文件进行管理(编辑后重新启动HTTP服务):
1 2 3 4 5 6
| <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。
- this does not work on xampp'的Apache。the问题仍然exists。
- 这是不安全的。请参阅这里的why;stackoverflow.com/questions/7564832/&hellip;
- 这是不安全的,正如@robquist所说。
在我的例子中,相同的代码在Firefox上运行得很好,但在Google Chrome上却不行。谷歌Chrome的javascript控制台说:
1 2 3
| 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正确匹配,然后它工作得很好。
并非所有服务器都支持JSONP。它要求服务器在其结果中设置回调函数。我使用它从返回纯JSON但不支持JSONP的站点获取JSON响应:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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;
});
} |
最后要注意的是,Mozilla文档明确指出
The above example would fail if the header was wildcarded as:
Access-Control-Allow-Origin: *. Since the Access-Control-Allow-Origin explicitly mentions http://foo.example,
the credential-cognizant content is returned to the invoking web
content.
因此,使用"*"不仅仅是一个坏习惯。根本不起作用。)
我使用Apache服务器,所以我使用了mod_代理模块。启用模块:
1 2
| LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so |
然后添加:
1
| ProxyPass /your-proxy-url/ http://service-url:serviceport/ |
最后,将代理URL传递到脚本。
乡亲们,
我也遇到了类似的问题。但使用小提琴,我能够解决这个问题。问题是,在Web API端的CORS实现中配置的客户机URL不能有一个尾随的正斜杠。通过Google Chrome提交请求并检查fiddler headers部分的textview选项卡后,错误消息的状态如下:
*"指定的策略来源u客户端u url://"无效。它不能以正斜杠结尾。"
这真的很奇怪,因为它在Internet Explorer上没有任何问题,但在使用Google Chrome进行测试时让我头疼。
我删除了CORS代码中的正斜杠并重新编译了Web API,现在可以通过Chrome和Internet Explorer访问该API,而不会出现任何问题。请试一试。
谢谢,安迪
上面由codegroover发布的解决方案中有一个小问题,如果您更改了一个文件,那么您必须重新启动服务器才能实际使用更新的文件(至少在我的情况下)。
所以搜索一下,我发现这一个可以使用:
1 2
| sudo npm -g install simple-http-server # to install
nserver # to use |
然后在以东十一〔二十二〕号服役。
- 虽然这个链接可以回答问题,但最好在这里包含答案的基本部分并提供链接以供参考。如果链接页发生更改,则仅链接答案可能无效。-从审查
- 澄清了链接。
我在Chrome上也有同样的错误(我没有测试其他浏览器)。这是因为我在domain.com而不是www.domain.com上导航。有点奇怪,但是我可以通过在.htaccess中添加以下行来解决这个问题。它将domain.com重定向到www.domain.com,问题解决了。我是一个懒惰的网络访问者,所以我几乎从不输入www,但显然在某些情况下,它是必需的。
1 2 3
| 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后解决了此错误。