我正在开发一个页面,通过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不允许使用null。
如果我直接从浏览器查询该URL,它可以正常工作。发生了什么,我可以解决这个问题吗?我是不是错误地编写了我的查询,或者这是因为Panoramio会阻碍我正在尝试做的事情?
Google没有在error message上找到任何有用的匹配。
修改
以下是一些显示问题的示例代码:
$().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...
});
});
答案 0 :(得分:416)
据记载,据我所知,你有两个问题:
您没有将“jsonp”类型说明符传递给$.get
,因此它使用的是普通的XMLHttpRequest。但是,如果服务器对其进行了确认,则您的浏览器支持CORS(跨源资源共享)以允许跨域XMLHttpRequest。这就是Access-Control-Allow-Origin
标题出现的地方。
我相信你提到过你是从file:// URL运行的。 CORS头有两种方式表示跨域XHR是正常的。一种是发送Access-Control-Allow-Origin: *
(如果你通过$.get
到达Flickr,它们必须一直在做),而另一种是回显Origin
标题的内容。但是,file://
网址会生成空Origin
,无法通过回送授权进行授权。
第一个问题是由Darin建议使用$.getJSON
以迂回方式解决的。如果它看到URL中的子串callback=?
,将请求类型从其默认的“json”更改为“jsonp”会有一点魔力。
通过不再尝试从file://
URL执行CORS请求,解决了第二个问题。
为了向其他人澄清,以下是简单的故障排除说明:
$.get
并将dataType
设置为jsonp
。$.getJSON
并添加了callback=?
。http://
进行测试。通过file://
运行的脚本对CORS的支持有限。答案 1 :(得分:74)
你需要在你的被调用脚本中添加一个HEADER,这是我在PHP中必须做的事情:
header('Access-Control-Allow-Origin: *');
Cross domain AJAX ou services WEB (法语)中的更多详细信息。
答案 2 :(得分:68)
对于一个简单的HTML项目:
cd project
python -m SimpleHTTPServer 8000
然后浏览您的文件。
答案 3 :(得分:20)
适用于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);
});
另外我建议您使用$.getJSON()
方法,因为之前的方法不适用于IE8(至少在我的机器上):
$.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);
});
您可以尝试online from here。
更新:
现在您已经显示了代码,我可以看到它的问题。您同时拥有匿名函数和内联函数,但两者都将被称为processImages
。这就是jQuery的JSONP支持的工作方式。请注意我如何定义callback=?
以便您可以使用匿名函数。您可以阅读更多about it in the documentation。
另一个评论是你不应该调用eval。传递给您的匿名函数的参数已经被jQuery解析为JSON。
答案 4 :(得分:8)
只要请求的服务器支持JSON数据格式,请使用JSONP(JSON Padding)接口。它允许您在没有代理服务器或花哨的标题内容的情况下发出外部域请求。
答案 5 :(得分:5)
这是same origin policy,您必须使用JSON-P接口或在同一主机上运行的代理。
答案 6 :(得分:4)
我们通过http.conf
文件管理它(编辑然后重新启动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 "*"
中,您可以输入准确的网址。
答案 7 :(得分:4)
如果您正在进行本地测试或从file://
之类的内容调用该文件,则需要禁用浏览器安全性。
在MAC上:
open -a Google\ Chrome --args --disable-web-security
答案 8 :(得分:3)
就我而言,相同的代码在Firefox上运行良好,但在Google Chrome上运行不正常。谷歌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网址的www部分,以便与原始网址正确匹配,然后就可以了。
答案 9 :(得分:2)
并非所有服务器都支持jsonp。它要求服务器在其结果中设置回调函数。我使用它来从返回纯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;
});
}
答案 10 :(得分:1)
我使用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传递给您的脚本。
答案 11 :(得分:1)
最后请注意Mozilla documentation explicitly says
如果标头是通配符,则上面的示例将失败: Access-Control-Allow-Origin:*。由于Access-Control-Allow-Origin明确提及http://foo.example, 凭证识别内容返回到调用Web 内容。
因此使用'*'不仅仅是一种不好的做法。根本不起作用:))
答案 12 :(得分:0)
我在Chrome中也遇到了同样的错误(我没有测试其他浏览器)。这是因为我在domain.com而不是www.domain.com上导航。有点奇怪,但我可以通过在.htaccess中添加以下行来解决问题。它将domain.com重定向到www.domain.com,问题解决了。我是一个懒惰的网络访问者,所以我几乎从不输入www,但显然在某些情况下它是必需的。
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
答案 13 :(得分:0)
在by CodeGroover above发布的解决方案中存在一个小问题,如果您更改文件,则必须重新启动服务器以实际使用更新的文件(至少在我的情况下)。
所以搜索一下,我发现this one要使用:
sudo npm -g install simple-http-server # to install
nserver # to use
然后它会在http://localhost:8000
投放。
答案 14 :(得分:0)
确保您使用的是最新版本的JQuery。我们在JQuery 1.10.2中遇到了这个错误,使用JQuery 1.11.1后错误得到了解决
答案 15 :(得分:0)
民间,
我遇到了类似的问题。但是使用Fiddler,我能够解决这个问题。问题是在Web API端的CORS实现中配置的客户端URL不能具有尾随正斜杠。在通过Google Chrome提交请求并检查Fiddler的标题部分的 TextView 标签后,错误消息指出如下内容:
*“指定的政策来源your_client_url:/'无效。不能以正斜杠结束。”
这真是古怪,因为它在Internet Explorer上没有任何问题,但在使用Google Chrome进行测试时让我头疼。
我删除了CORS代码中的正斜杠并重新编译了Web API,现在可以通过Chrome和Internet Explorer访问API而不会出现任何问题。请试一试。
谢谢, 安迪
答案 16 :(得分:0)
对于PHP-适用于Chrome,Safari和Firefox的这项工作
header('Access-Control-Allow-Origin: null');
使用axios通过File://调用php实时服务