解决Ajax跨域问题,目前大概有4种方案。下面我重点讲述目前流行的解决方案---用服务器代理(中间过渡)的解决方案。中间过渡,就是在Ajax与不同域的服务器进行通讯的中间加一层过渡,这一层过渡可以是PHP、JSP、ASP、Servlet等任何具备网络通讯功能的语言,由中间层向不同域的服务器进行读取数据的操作。<o:p></o:p>
下面我用Servlet为服务器代理,用Step by Step的方式,以一个读取异域RSS的例子,讲述这种解决方案。<o:p></o:p>
<!--[if !supportLists]-->1、 <!--[endif]-->首先在MyEclipse中,建立一个web project。然后,新建一个html文件,取名为ReadRSS.html.
此html文件的作用包括:
(1)、向本地服务器发送请求,通过本地服务器中的Servlet,向远程服务器拿rss文件。代码为:XML_Http_Request.open("GET",url,true); //true---异步;false---同步。注意,这里的url为:var url="proxyServlet?RSS_URL="+url;这里的proxyServlet是本地服务器上的文件。
(2)、显示rss文件。processRequest函数将rss文件打印出来。
<!--[if !supportLineBreakNewLine]-->
<!--[endif]--><o:p></o:p>
代码如下:<o:p></o:p>
<html><o:p></o:p>
<head><o:p></o:p>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><o:p></o:p>
<title>ReadRSS</title><o:p></o:p>
<script language="javascript"><o:p></o:p>
var XML_Http_Request = false;<o:p></o:p>
<o:p></o:p>
function createXMLHttpRequest(){<o:p></o:p>
XML_Http_Request = false;<o:p></o:p>
<o:p></o:p>
if(window.XMLHttpRequest){ //for Mozilla<o:p></o:p>
XML_Http_Request = new XMLHttpRequest();<o:p></o:p>
if(XML_Http_Request.overrideMimeType){<o:p></o:p>
XML_Http_Request.overrideMimeType("text/xml");<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
else if(window.ActiveXObject){ //for IE<o:p></o:p>
try{<o:p></o:p>
XML_Http_Request = new ActiveXObject("Msxml2.XMLHTTP");<o:p></o:p>
}catch(e){<o:p></o:p>
try{<o:p></o:p>
XML_Http_Request = new ActiveXObject("Microsoft.XMLHTTP");<o:p></o:p>
}catch(e){}<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
} <o:p></o:p>
<o:p></o:p>
function send_Request(url){<o:p></o:p>
/*The function send_request has some other parameters.<o:p></o:p>
function send_request(url,Parameter1,Parameter2,...,Parametern){<o:p></o:p>
*/<o:p></o:p>
var url="proxyServlet?RSS_URL="+url;<o:p></o:p>
createXMLHttpRequest();<o:p></o:p>
<o:p></o:p>
if(!XML_Http_Request){<o:p></o:p>
window.alert("Cannot create XMLHttpRequest instance!");<o:p></o:p>
return false;<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
XML_Http_Request.onreadystatechange = processRequest;<o:p></o:p>
/*The function processRequest has some parameters.<o:p></o:p>
XML_Http_Request.onreadystatechange = function(){<o:p></o:p>
processRequest(Parameter1,Parameter2,...,Parametern);<o:p></o:p>
};<o:p></o:p>
*/<o:p></o:p>
<o:p></o:p>
XML_Http_Request.open("GET",url,true); //true---异步;false---同步<o:p></o:p>
XML_Http_Request.send(null);<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
function processRequest(){<o:p></o:p>
/*The function processRequest has some parameters.<o:p></o:p>
function processRequest(Parameter1,Parameter2,...,Parametern){<o:p></o:p>
*/<o:p></o:p>
if(XML_Http_Request.readyState == 4) {<o:p></o:p>
if(XML_Http_Request.status == 200) { <o:p></o:p>
/*******************************************************************************/<o:p></o:p>
//statements <o:p></o:p>
var results = XML_Http_Request.responseXML;<o:p></o:p>
var title = null;<o:p></o:p>
var item = null;<o:p></o:p>
var link = null;<o:p></o:p>
var description = null;<o:p></o:p>
var ccc = results.getElementsByTagName("channel");<o:p></o:p>
var headtitle = ccc[0].getElementsByTagName("title")[0].firstChild.nodeValue;<o:p></o:p>
var headlink = ccc[0].getElementsByTagName("link")[0].firstChild.nodeValue;<o:p></o:p>
var cell = document.createElement("div");<o:p></o:p>
cell.innerHTML = "<h1><a href="+headlink+" target=_blank>"+headtitle+"</a></h1><br>";<o:p></o:p>
document.getElementById("result").appendChild(cell);<o:p></o:p>
var items = results.getElementsByTagName("item");<o:p></o:p>
for(var i = 0; i < items.length; i++) {<o:p></o:p>
item = items[i];<o:p></o:p>
link=item.getElementsByTagName("link")[0].firstChild.nodeValue;<o:p></o:p>
title = item.getElementsByTagName("title")[0].firstChild.nodeValue;<o:p></o:p>
var cell = document.createElement("div");<o:p></o:p>
cell.innerHTML = "<li><a href="+link+" target=_blank>"+title+"</a></li><br>";<o:p></o:p>
document.getElementById("result").appendChild(cell);<o:p></o:p>
}<o:p></o:p>
/*******************************************************************************/<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
</script><o:p></o:p>
</head><o:p></o:p>
<body onLoad="javascript:send_Request('http://localhost:7001/AjaxProxy/rss2.xml');"><o:p></o:p>
<div id="result"><o:p></o:p>
</div><o:p></o:p>
</body>
</html><o:p></o:p>
<!--[if !supportLists]-->2、 <!--[endif]-->新建一个servlet,命名为ProxyServlet.java。修改web.xml文件,<url-pattern>ProxyServlet</url-pattern>,以匹配html向本地服务器请求的地址。这样,将html与servlet连接起来,让servlet来获取异域rss的xml文件。ProxyServlet.java主要功能是将异域rss的xml文件response出来。<o:p></o:p>
代码如下:<o:p></o:p>
package action;<o:p></o:p>
import java.io.IOException;<o:p></o:p>
import java.io.InputStream;<o:p></o:p>
import java.io.OutputStream;<o:p></o:p>
import java.net.URL;<o:p></o:p>
import java.net.URLConnection;<o:p></o:p>
import javax.servlet.ServletException;<o:p></o:p>
import javax.servlet.http.HttpServlet;<o:p></o:p>
import javax.servlet.http.HttpServletRequest;<o:p></o:p>
import javax.servlet.http.HttpServletResponse;<o:p></o:p>
<o:p> </o:p>
public class ProxyServlet extends HttpServlet {<o:p></o:p>
private static final long serialVersionUID = <st1:chmetcnv w:st="on" unitname="l" sourcevalue="1" hasspace="False" negative="False" numbertype="1" tcsc="0">1L</st1:chmetcnv>;<o:p></o:p>
private int READ_BUFFER_SIZE = 1024;<o:p></o:p>
<o:p> </o:p>
public void doGet(HttpServletRequest request, HttpServletResponse response)<o:p></o:p>
throws ServletException, IOException {<o:p></o:p>
String urlString = request.getParameter("RSS_URL");<o:p></o:p>
writeResponse(response, urlString);<o:p></o:p>
}<o:p></o:p>
<o:p> </o:p>
private void writeResponse(HttpServletResponse response, String urlString) throws ServletException{<o:p></o:p>
try {<o:p></o:p>
URL url = new URL(urlString);<o:p></o:p>
URLConnection urlConnection = url.openConnection();<o:p></o:p>
response.setContentType(urlConnection.getContentType());<o:p></o:p>
InputStream ins = urlConnection.getInputStream();<o:p></o:p>
OutputStream outs = response.getOutputStream();<o:p></o:p>
byte[] buffer = new byte[READ_BUFFER_SIZE];<o:p></o:p>
int bytesRead = 0;<o:p></o:p>
while ((bytesRead = ins.read(buffer, 0, READ_BUFFER_SIZE)) != -1) {<o:p></o:p>
outs.write(buffer, 0, bytesRead);<o:p></o:p>
}<o:p></o:p>
System.out.println(outs);<o:p></o:p>
outs.flush();<o:p></o:p>
outs.close();<o:p></o:p>
ins.close();<o:p></o:p>
} catch (Exception e) {<o:p></o:p>
try {<o:p></o:p>
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());<o:p></o:p>
} catch (IOException ioe) {<o:p></o:p>
throw new ServletException(ioe);<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
}