Saturday, March 21, 2009

关于JS的跨域访问

上周在写一个小工具, 简易的字典翻译功能. 由于用的是其它网站的字典数据, 所以最大的技术细节就是跨域访问了. 什么是跨域访问? 说白了就是访问非本地服务器上的内容. 比如我想通过我这台服务器上的网页来查看其它网站的内容就属于这种情况. 这种行为在JS中是严厉禁止的, 被叫做"The Same-Origin Policy"

当然, 网上也流传着很多破解这条规定的方法. 有通过在server上配置"代理"的, 有调整Apache配置的, 还有通过<iframe><script>标签来迂回的. 对于第二种, 通用性不高, 要是遇到非Apache服务器就没辙了. 第三种, 恕我才疏学浅, 看了几篇文章都没搞明白到底该怎么弄. 第一种倒是在几篇文章的帮助下成功了, 遂记之.

首先讲下原理, 由于JS被禁止直接访问, 所以我们就采用迂回战术, 通过服务器上另一个页面作为中转, 再传递给JS处理, 这个和平时使用的通过代理服务器来中转, 以便查看一些被墙的网页是一个道理.

我用的是PHP页面来作为中转, 这个页面的功能是把目标网页的源代码传送回来. 代码是用的这个网站的, 里面也介绍了上面的另外两种方法, 有兴趣的同学可以去看看.
$ cat proxy.php
<?php
$url = $_GET['path'];
$session = curl_init($url);

// Don't return HTTP headers. Do return the contents of the call.
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// Make the call.
$html = curl_exec($session);

// The web service returns HTML.
header("Content-Type: text/html; charset=gbk");

echo $html;
curl_close($session);
?>
需要注意的是, 这段代码要求server的PHP具有cURL模块的支持. 非常不爽的一点就是, Win下PHP只需要改下配置文件就可以使用cURL了, 而Linux下则必须重新编译一次PHP才行. 你需要先下载cURL, 然后是常规的编译安装三部曲, 具体的编译参数可以参照./configure --help自行调整:
$ ./configure --enable-http --enable-file
$ make
$ sudo make install
接着是编译PHP, 在编译参数里面添加两个参数:
$ ./configure --with-curl=/usr/local --with-curlwrappers
/usr/local是默认安装地址, 如果你没有改的话. 最后修改PHP的配置文件, 添加:
extension=curl.so
这样上面那段PHP代码就能正常执行了.

有了上面PHP的支持, 剩下的操作就易如反掌了, 和本地就没什么区别了, 想怎么弄就怎么弄, 嘿嘿~ 思路上很大程度上是受了这篇文章的影响, 虽然最后没有用上文中介绍的JSON, 但还是发现JSON是个很好很强大的东西. 下面的JS代码示例中用了jQuery中的API作为AJAX的简化操作, 这也是我第一次用jQuery, 发现这个也挺爽的, 包装了很多有用的功能, 也算偷了下懒. 示例代码部分:
$.get(
       "proxy.php",
       { path: "http://www.google.com/" },
       function(data)
       {
         // Do something on data...
       },
       "html"
     );
余下的就看你的需求了, end.

No comments:

Post a Comment