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

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

解决Ajax跨域问题,目前大概有4种方案。下面我重点讲述目前流行的解决方案---用服务器代理(中间过渡)的解决方案。中间过渡,就是在Ajax与不同域的服务器进行通讯的中间加一层过渡,这一层过渡可以是PHPJSPASPServlet等任何具备网络通讯功能的语言,由中间层向不同域的服务器进行读取数据的操作。

下面我用Servlet为服务器代理,用Step by Step的方式,以一个读取异域RSS的例子,讲述这种解决方案。

1、  首先在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文件打印出来。

    代码如下:

   <html>

   <head>

   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

   <title>ReadRSS</title>

   <script language="javascript">

   var XML_Http_Request = false;

    

   function createXMLHttpRequest(){

       XML_Http_Request = false;

      

       if(window.XMLHttpRequest){        //for Mozilla

           XML_Http_Request = new XMLHttpRequest();

           if(XML_Http_Request.overrideMimeType){

              XML_Http_Request.overrideMimeType("text/xml");

           }

       }

       else if(window.ActiveXObject){   //for IE

           try{

              XML_Http_Request = new ActiveXObject("Msxml2.XMLHTTP");

           }catch(e){

              try{

                  XML_Http_Request = new ActiveXObject("Microsoft.XMLHTTP");

              }catch(e){}

           }

       }

    }   

   

    function send_Request(url){

    /*The function send_request has some other parameters.

    function send_request(url,Parameter1,Parameter2,...,Parametern){

    */

       var url="proxyServlet?RSS_URL="+url;

       createXMLHttpRequest();

   

       if(!XML_Http_Request){

           window.alert("Cannot create XMLHttpRequest instance!");

           return false;

       }

       

       XML_Http_Request.onreadystatechange = processRequest;

       /*The function processRequest has some parameters.

       XML_Http_Request.onreadystatechange = function(){

           processRequest(Parameter1,Parameter2,...,Parametern);

       };

       */

      

       XML_Http_Request.open("GET",url,true);   //true---异步;false---同步

       XML_Http_Request.send(null);

    }

   

    function processRequest(){

    /*The function processRequest has some parameters.

    function processRequest(Parameter1,Parameter2,...,Parametern){

    */

       if(XML_Http_Request.readyState == 4) {

           if(XML_Http_Request.status == 200) { 

   /*******************************************************************************/

               //statements 

              var results = XML_Http_Request.responseXML;

              var title = null;

              var item = null;

              var link = null;

               var description = null;

              var ccc = results.getElementsByTagName("channel");

              var headtitle = ccc[0].getElementsByTagName("title")[0].firstChild.nodeValue;

              var headlink = ccc[0].getElementsByTagName("link")[0].firstChild.nodeValue;

              var cell = document.createElement("div");

              cell.innerHTML = "<h1><a href="+headlink+" target=_blank>"+headtitle+"</a></h1><br>";

              document.getElementById("result").appendChild(cell);

              var items = results.getElementsByTagName("item");

              for(var i = 0; i < items.length; i++) {

                  item = items[i];

                  link=item.getElementsByTagName("link")[0].firstChild.nodeValue;

                  title = item.getElementsByTagName("title")[0].firstChild.nodeValue;

                  var cell = document.createElement("div");

                  cell.innerHTML = "<li><a href="+link+" target=_blank>"+title+"</a></li><br>";

                    document.getElementById("result").appendChild(cell);

              }

   /*******************************************************************************/

           }

       }

    }

   </script>

   </head>

   <body onLoad="javascript:send_Request('http://localhost:7001/AjaxProxy/rss2.xml');">

   <div id="result">

   </div>

   </body>
 </html>

2、  新建一个servlet,命名为ProxyServlet.java。修改web.xml文件,<url-pattern>ProxyServlet</url-pattern>,以匹配html向本地服务器请求的地址。这样,将htmlservlet连接起来,让servlet来获取异域rssxml文件。ProxyServlet.java主要功能是将异域rssxml文件response出来。

  代码如下:

package action;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.URL;

import java.net.URLConnection;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

public class ProxyServlet extends HttpServlet {

    private static final long serialVersionUID = 1L ;

    private int READ_BUFFER_SIZE = 1024;

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

        String urlString = request.getParameter("RSS_URL");

        writeResponse(response, urlString);

    }

 

    private void writeResponse(HttpServletResponse response, String urlString) throws ServletException{

        try {

            URL url = new URL(urlString);

            URLConnection urlConnection = url.openConnection();

            response.setContentType(urlConnection.getContentType());

            InputStream ins = urlConnection.getInputStream();

            OutputStream outs = response.getOutputStream();

            byte[] buffer = new byte[READ_BUFFER_SIZE];

            int bytesRead = 0;

            while ((bytesRead = ins.read(buffer, 0, READ_BUFFER_SIZE)) != -1) {

                outs.write(buffer, 0, bytesRead);

            }

            System.out.println(outs);

            outs.flush();

            outs.close();

            ins.close();

        } catch (Exception e) {

            try {

                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());

            } catch (IOException ioe) {

                throw new ServletException(ioe);

            }

        }

    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值