解决Javascript跨域访问RSS问题

问题出在我写即时天气插件的时候。
这个天气插件呢,是通过抓取服务商(我选了MSN)提供的即时天气情况的RSS连接,来显示博主所在地当前天气状况的一个小功能。
我在本地调试插件的时候,先把天气情况的RSS保存到本地,加载本地的XML,一路通常地调通了程序,但是在实际测试的时候出现了问题。
当试图通过XMLHttpRequest对象访问http://weather.msn.com/rss.aspx来获得当前的天气情况的时候IE却提示没有权限,Firefox2.0的Debugger则提示了一堆不知所谓的乱码。把XML改成本地的,问题立即消失。心下估么着,八成是Javascript出于安全性考虑,不允许跨域调用资源造成的。
没辙,只好求助Google,Google了一下“Javascript 跨域 RSS”这个关键字之后,想法得到了证实。接下来却又郁闷于如何解决这个问题。在网上大致找到了几种方法,一种是在后台做代理,或者是Apache的Rewrite或者是Proxy模块,document.domain等等的。只不过一来我等小虾没有自己的服务器,改http.conf用速度最快的Rewrite方法是与我无缘了,我和MSN的域名相差甚远,眼看document.domain也没戏。这下只好用PHP做一个代理了。
在网上找到了下面代码(出处,注释我翻译了一下):PHP Code:
<?
// 指定域名
define('HOSTNAME', 'http://api.local.yahoo.com/');
// 从AJAX进程中获得后面的请求地址
$path = $_GET['path'];

// 将域名和地址组合
$url = HOSTNAME.$path;
// 打开Curl进程
$session = curl_init($url);
// 不返回HTTP头,只返回服务器应答内容。
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// 发起请求
$xml = curl_exec($session);

// WEB服务器发送XML头
header("Content-Type: text/xml");

echo $xml;
curl_close($session);
?>
连看都没看,简单改了一下地址,直接放到程序里面,服务器提示Fatal error: Call to undefined function curl_init()。继续郁闷……
看来只好用苯方法了,但是却比较管用:PHP Code:
<?
$url = "http://weather.msn.com/rss.aspx?wealocations=wc:CHXX0046&weadegreetype=C";
header("Content-Type: text/xml");
$content = file_get_contents($url);
echo $content;
?>
之后保存为weather.php,前台的Ajax向这个weather.php提交请求之后,这个后台代理从别人那里抓了XML内容再输出出来给Ajax看,Javascript一看是本地资源自然高兴,于是按照我的意思就显示了天气出来。这么做虽然增加了服务器负担,但是因为不能动用Rewrite模块,这也是不得已而为之。
ASP、.NET的代理,网上也都能找到现成的代码,既然是玩PHP的,这里就不现眼了。
当然,以上是比较基础的方法,如果你的Blog流量特别巨大,急切希望减小带宽和请求次数开销,可以在服务器段做缓存,N小时更新一次,如果连服务器缓存都支撑不了……-0- 可以尝试用Javascript在客户端的cookie里面放一些东西也不是不可以……只要你的客户们愿意就可以……如果还是不满意的话,可以默认客户端不显示博主当前天气状况,如果用户想看了,就点击相应的链接,触发Ajax,之后就是照常提交请求、接收回应等等。

(别问我为什么MSN提供的天气资料是英文的,我这显示出来的却是中文的…因为我在weather.php里面动了点手脚,把相应的词语都已换成中文了 囧)

《解决Javascript跨域访问RSS问题》上有1条评论

评论已关闭。