我在名为kopernikus.science.net
的服务器上有一个JavaScript,它希望访问名为galileo.science.net
的其他服务器上的文件。这是我想到的一个玩具示例:
code residing on http://kopernikus.science.net/makecalendar.js :
var request = new XMLHttpRequest();
request.open("GET","galileo.science.net/calendar", false);
request.send(null);
document.getElementById("calendar").innerHTML =
"<div>" + request.responseText.split('\n')[0] + "</div>";
不幸的是,由于现代网络浏览器的“同源策略”,禁止脚本访问不同域的数据。
当然,我的问题是:
我怎样才能访问远程文件?
允许JavaScript之外的解决方案,例如镜像相关文件或调整
.htaccess
。我有什么选择?哪个需要Web服务器上的权限最少?
有问题的文件是vcalendar格式的日历,会定期更改。我在共享主机上,没有sysadmin权限,但我可以运行PHP和CGI脚本,可以更改.htaccess
文件的某些部分。
答案 0 :(得分:8)
一些选项:
XDomainRequest
而不是XMLHttpRequest
(其他浏览器,如Chrome和Firefox,使用XMLHttpRequest
完全透明地处理CORS。)document.domain
指定这两个页面(如果它们实际上是同一个science.net
域的子域)位于同一个源中。这在浏览器中运行良好,但它的缺点是您首先必须将目标文档加载到窗口(可能是隐藏的iframe)才能访问它,因为目标文档也必须设置document.domain
(表明它希望与您合作)。大致按照我使用它们的顺序列出。例如,如果您控制服务器并且知道您的客户将使用最新的浏览器,则使用CORS;如果没有,请查看JSONP(虽然从下面的评论中,你可能不能);如果不是其中任何一个,也许document.domain
就是答案;等等,在列表中工作到最后的选择(代理)。
答案 1 :(得分:1)
不幸的是,由于“相同的起源 现代网络浏览器的政策, 脚本被禁止访问 不同域名的数据。
但你可以做的是使用json-p。
脚本和JSONP请求不是 受同一原产地政策约束 限制。
<!DOCTYPE html>
<html>
<head>
<style>img{ height: 100px; float: left; }</style>
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
</head>
<body>
<div id="images">
</div>
<script>
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
tags: "cat",
tagmode: "any",
format: "json"
},
function(data) {
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
if ( i == 3 ) return false;
});
});</script>
</body>
</html>
作为旁注,现代浏览器支持CORS(Internet Explorer 8 +,Firefox 3.5 +,Safari 4+和Chrome)。
答案 2 :(得分:1)
假设您可以在kopernikus.science.net上部署PHP,为什么不在那里代理它...
<?php
header('Content-Type: application/x-javascript');
print file_get_contents('http://galileo.science.net/calendar');
(当然,您可以在代理和客户端上暂时缓存它以减少网络噪音)
<强>更新强>
如果你想缓存....
<?php
header('Content-Type: application/x-javascript');
define("CACHEDIR", '/tmp/webcache/');
$cache_time=14 * 24 * 60 * 60; // cache for 2 weeks
$key=sha1('http://galileo.science.net/calendar');
if (@filemtime(CACHEDIR . $key) > time() - $cache_time) { // cache good
print file_get_contents(CACHEDIR . $key);
} else { // cache stale
$freshcopy=file_get_contents('http://galileo.science.net/calendar');
print $freshcopy;
if (!file_put_contents(CACHEDIR . $key, $freshcopy)) {
// report a problem writing files
}
}
答案 3 :(得分:0)
使用JSONP。在javascript中,在页面中嵌入一个新的脚本元素,该页面具有另一个服务器的接口作为源。
服务器应该返回如下内容:
callCallback({"some":"JSONString"});
答案 4 :(得分:0)
这是一个众所周知的问题,JSONP是问题的解决方案。你可以google并提供大量的信息。您可以将此视为使用JSONP和使用jQuery的示例。
http://www.beletsky.net/2010/07/json-jsonp-and-same-origin-policy-issue.html