• AJAX跨域问题


            最近遇到一个项目,你的JSP网页和服务器提供的服务不在一个域中,但是需要通过AJAX方式来跨域调用服务器的服务,例如

    你的JSP页面:http://192.168.6.26:7001/First_Web/TestXML.jsp

    服务器的服务地址:http://10.8.2.60:9082/PGIS_S_Map/XMLPort

            众所周知,AJAX是不能跨域的,因为跨域访问会涉及很严重的安全问题,不仅是AJAX技术,采用任何方式(例如表单post)来跨域访问都会涉及严重的问题。例如你在你的网站中通过AJAX去跨域修改网站B后台服务器的数据,这里面当然会涉及到权限问题,如果权限被绕过(例如通过CSRF,XSS等技术窃取网站B的cookies),跨域访问又被允许的情况下,网站B的后台数据就会被窃取和破坏。

           目前AJAX跨域解决方式主要有以下几种:

    一、主域名相同,子域名不同

         例如:http://www.aa.com/和book.aa.com,主域名都是aa.com,

         解决方式:此时可以通过设置document.domain方式解决,具体可以参考http://blog.sina.com.cn/s/blog_62449fcf0100p3bp.html


    二、域名完全不同

         例如我在项目中遇到的就是这种情况,这种情况又可以分为两类:

         1)客户端只需要通过get方式来跨域请求服务端的服务

         解决方式:jQuery+jsonp

           具体可参考:http://www.biaodianfu.com/json-jsonp.html

         2)客户端需要通过POST和GET方式来跨域请求服务端的服务

         解决方式:中转代理方式,客户端在本地建立一个Servlet和JSP做中转代理,先将请求发送到代理,代理将请求转发到服务器,并接收反馈结果,并将结果返回到客户端

           下面介绍代理方式:

    1)客户端TestXML.jsp,其中txtInput用于输入请求的xml数据,txtOutput用于输出返回的XML数据,客户端将请求的XML数据和服务器的服务地址一致发送给代理ClientServlet

    <%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title>test XML</title>
         <SCRIPT LANGUAGE="JavaScript"> 
         
    var XMLHttpReq;   
        
    //创建XMLHttpRequest对象,通过XMLHttpRequest请求服务器端的数据        
        function createXMLHttpRequest() {                
            
    if(window.XMLHttpRequest) { //Mozilla 浏览器   
                XMLHttpReq = new XMLHttpRequest();   
            }   
            
    else if (window.ActiveXObject) { // IE浏览器   
                try {   
                    XMLHttpReq 
    = new ActiveXObject("Msxml2.XMLHTTP");   
                }
    catch (e) {   
                    
    try {   
                        XMLHttpReq 
    = new ActiveXObject("Microsoft.XMLHTTP");   
                    } 
    catch (e) {}   
                }   
            }   
        }   
        
    //发送请求函数到服务器,这里服务器的处理程序为servlet程序   
        function sendRequest() 
        {   
            document.getElementById(
    "txtOutput").innerHTML ="正在查询,请您稍等......";    
            createXMLHttpRequest();   
            
            
    var xmldata = "xml="+document.getElementById("txtInput").value;
            
    var urldata = "url=http://10.8.2.60:9082/PGIS_S_Map/XMLPort";
            
            
    var url = "Client";   
            
    var param = xmldata+"&"+ urldata;
               
            XMLHttpReq.open(
    "post",url,true);   
            XMLHttpReq.setRequestHeader(
    "Content-Type","application/x-www-form-urlencoded");   
            XMLHttpReq.onreadyStatechange
    = XMLHttpReq.onreadystatechange = processResponse;  
            XMLHttpReq.send(param);
        }   
        
    //处理服务器端返回的信息函数   
        function processResponse() {   
            
    if (XMLHttpReq.readyState == 4) { // 判断对象状态   
                if (XMLHttpReq.status == 200) { // 信息已经成功返回,开始处理信息   
                    Display();   
               } 
    else { //页面不正常   
                    window.alert("您所请求的页面有异常。");   
                }   
            }   
        }   
        
    //网页局部刷新,显示服务器端返回的数据
        function Display() {   
               
    var msg=XMLHttpReq.responseText;   
               document.getElementById(
    'txtOutput').value=msg;    
        }   
    </SCRIPT>
    </head>

    <body>
    <TEXTAREA ID=txtInput rows=15 style=" 100%"></TEXTAREA>
    <input type="button" value="显示结果!" onClick="sendRequest();"> 
    <TEXTAREA ID=txtOutput rows=15 style=" 100%"></TEXTAREA>
    </body>
    </html>

    2)服务器端ClientServlet,解析服务器传送过来的xml数据和服务地址,并将xml数据转发到该服务地址

    package Sql;

    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;

    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;


    public class ClientServlet extends HttpServlet {

        public void init(ServletConfig config) throws ServletException {
            super.init();
        }

        public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
        {
                
        }
        
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
        {
            try 
            {
            //获取需要提交的xml数据和转发的url地址
            String urldata = new String(request.getParameter("url").getBytes("iso-8859-1"), "utf-8");
            String xmldata = new String(request.getParameter("xml").getBytes("iso-8859-1"), "utf-8");

            //设置url连接
            URL url = new URL(urldata);     
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
            conn.setRequestMethod("POST"); // 提交模式   
            
    //conn.setConnectTimeout(10000);//连接超时 单位毫秒  
            conn.setReadTimeout(9000);//读取超时 单位毫秒 这一部分可以相对设大一点 避免时间过短 数据传送不回来 出现java.net.SocketTimeoutException: Read timed out错误 
            conn.setDoOutput(true);// 是否输入参数  
            
            
    //提交xml数据到该url
            StringBuffer params = new StringBuffer();     
            // 表单参数与get形式一样       
            params.append("xml").append("=").append(xmldata);       
            byte[] bypes = params.toString().getBytes();      
            conn.getOutputStream().write(bypes);// 输入参数     
            
            
    //获取从该url反馈回来的数据,并将该数据返回到ajax客户端
            BufferedInputStream in = new BufferedInputStream(conn.getInputStream());    
            byte[] bs = new byte[1024];
            int startpos = 0;
            int num = 0;
            num = in.read(bs, startpos, 1024);
            OutputStream out = response.getOutputStream();
            while (num != -1) {
                out.write(bs, 0, num);
                num = in.read(bs, 0, 1024);
            }
            
            //释放内存
            out.flush();
            out.close();
            in.close();
            conn.disconnect();
            } 
            catch (Exception e) 
            {
                e.printStackTrace();
            } 
            
        }
    }

    3)服务器web.xml配置

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" 
        xmlns
    ="http://java.sun.com/xml/ns/j2ee" 
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation
    ="http://java.sun.com/xml/ns/j2ee 
        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    >
       
        
      <servlet>
        <servlet-name>ClientServlet</servlet-name>
        <servlet-class>Sql.ClientServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>ClientServlet</servlet-name>
        <url-pattern>/Client</url-pattern>
      </servlet-mapping>

      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>

         此外,AJAX跨域还有其他几种方式,具体可以参见

          http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html

          http://zhaohe162.blog.163.com/blog/static/3821679720113219250547/

          http://www.blogjava.net/itspy/archive/2007/02/11/99262.html

     

  • 相关阅读:
    性能调优利器之strace
    如何写出优雅的Python(二)
    c# 模拟 网页实现12306登陆、自动刷票、自动抢票完全篇
    使用Javascript无限添加QQ好友原理解析
    微信公众账号开发之微信登陆Oauth授权-第一篇
    WPF下的仿QQ图片查看器
    不用写软件,纯JS 实现QQ空间自动点赞
    软件分层架构下的另类设计框架-工厂模式的使用
    Javascript实现Linq查询方式
    c# 使用正则表达式 提取章节小说正文全本篇
  • 原文地址:https://www.cnblogs.com/king1302217/p/2643585.html
Copyright © 2020-2023  润新知