XMLHttpRequest对象(在IE中也称作XMLHTTP对象)是当今最令人兴奋的AJAX Web应用程序的核心。但实际上使用这个对象书写的客户端web应用程序在通过web浏览器进行跨域访问时面临的安全限制性因素而变的非常棘手。这篇文章以简单易于理解的语言描述了这个问题,并提供了一个可行的解决方案:来自你的web服务器请求像雅虎的web服务API网络请求的web代理。

为什么需要代理

所有现代的Web浏览器在网络连接上增加了安全性的限制,其中包括XMLHttpRequest调用。可中安全性限制可以防止脚本或应用程序访问和操作另外一个域的属性和方法(在IE浏览器中的首选参数中如果该选项被设置为可用,则允许跨域请求)。如果你的Web应用程序和应用程序所需的XML数据都是来自同一个服务器,则不会有这种限制。

然而,如果你要为你的web应用程序提供其他服务器上的服务,例如,雅虎的Web服务,那么浏览器将会阻止这种访问

这里有不少解决这个问题的方案,但最常用的是在你的Web服务器上使用代理,这样你就不需要使用XMLHttpRequest对象直接访问雅虎的Web服务,而是去访问你的web服务器上的代理服务,这个代理可以根据你的请求去调用雅虎的Web服务,并将请求返回的数据返回到客户端,因为XMLHttpRequest请求的是你自己的服务器,因此就不会存在浏览器的安全性限制问题。

出于安全因素,在你web服务器上使用代理访问服务应该使用有所限制的,一个连接到任何网站的URL的开发代理是很容易被滥用的。虽然很难限制只用你的应用程序连接到代理,但是你可以在代理服务器上指定代理所能访问的服务.

用PHP代理访问雅虎的Web服务

JavaScript Developer Center提供了一段用PHP写的简单web代理,它是用来代理访问雅虎的搜索服务API的,你可以将这段简单的Web代理代码拷贝到你Web服务的的任意方便的位置,前提是你的Web服务可以运行PHP程序。

define ('HOSTNAME', 'http://search.yahooapis.com/');

more complete XMLHttpRequest code sample

然后你的客户端就可以像下面这样使用XMLHttpRequest进行访问了

// The web services request minus the domain name
var path = 'VideoSearchService/V1/videoSearch?appid=YahooDemo&query=madonna&results=2';

// The full path to the PHP proxy
var url = 'http://localhost/php_proxy_simple.php?yws_path=' + encodeURIComponent(path);
... // core xmlhttp code
xmlhttp.open('GET', url, true);

其他解决方案

除了使用Web代理可以传输web服务数据到你的web应用程序,这里还用几种绕过浏览跨域访问限制的方法:

  • 使用apache的 mod_rewrite or mod_proxy模块转发对你服务器的请求到其他服务器。
  • 使用JSON和动态的<script>标签来代替XMLHttpRequest,也就是所谓的JSONP。
  • Digitally sign your scripts,这种方式只在Firefox浏览器中可以使用,其他浏览器不可用。

了解更多信息

想对JavaScript, XMLHttpRequest, Yahoo! Web Services APIs以及其他javascript开发的话题,访问The Yahoo! Developer Network JavaScript Developer Center.

英文地址:http://developer.yahoo.com/javascript/howto-proxy.html

翻译的不好,莫喷,实际上本文介绍的方法,也是笔者经常使用的一种方法,其实就是使用PHP中的CURL模块,在服务端模拟浏览器的请求动作实现服务的代理。