用服务器代理(Servlet)解决Ajax跨越问题

Ajax 从诞生那天起,xmlHttprequest对象不能跨域请求的问题就一直存在。跨域请求,简单来说,本地的HTML文件只能够访问本地的XML数据源,而不能够访问到其他服务器上的XML数据源文件。xmlHttprequest对象这种特性,是基于网络的安全策略。这些我在这里不详细展开。xmlHttprequest的这种安全策略,在提供安全性的同时,也引进一些限制,如,读取异域的RSS<o:p></o:p>

解决Ajax跨域问题,目前大概有4种方案。下面我重点讲述目前流行的解决方案---用服务器代理(中间过渡)的解决方案。中间过渡,就是在Ajax与不同域的服务器进行通讯的中间加一层过渡,这一层过渡可以是PHPJSPASPServlet等任何具备网络通讯功能的语言,由中间层向不同域的服务器进行读取数据的操作。<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向本地服务器请求的地址。这样,将htmlservlet连接起来,让servlet来获取异域rssxml文件。ProxyServlet.java主要功能是将异域rssxml文件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>

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值