zoukankan      html  css  js  c++  java
  • WEB跨域问题

    跨域主要分为ajax跨域和iframe跨域:

      ajax跨域:在一个window中请求另一个项目的数据,域名发生改变,即为ajax跨域。要支持ajax跨域有几种方式,如:jsonp,CORS等。这里主要介绍CORS方式。

      iframe跨域:iframe本身是支持跨域的,即在一个域名下的window支持请求另一个域名下的数据显示到iframe,而不会产生跨域问题。但此跨域iframe中不允许访问父window中的属性和函数。即parent.var和top.var和parent.fn和top.fn会出现跨域异常,此时主要解决的是跨域数据传输问题。

    CORS跨域:

      CORS跨域的主要思想是自定义HTTP响应头从而让浏览器和跨域服务器通信。默认情况下跨域访问时在ajax和http协议中都是不被支持的,为啦支持跨域ajax跨域,请求和响应都必须设置跨域支持参数。

      请求参数:使用jquery时设置crossDomain:true,如果要携带cookie需增加参数xhrFields: {withCredentials: true}。则请求格式为:

     1 $.ajax({
     2             crossDomain:true,
     3             xhrFields: {
     4                  withCredentials: true
     5             },
     6             url:url,
     7             data : data,
     8             success: function(data, statusText, xhr){
     9                    
    10             }
    11    }); 

      响应参数:响应时浏览器接收响应的响应头的响应域名与当前域名不一致,也是不被接受的,会报跨域异常,除非响应头中包含该域名的访问控制允许的参数

       HttpServletResponse response = (HttpServletResponse) res;  
            response.setHeader("Access-Control-Allow-Origin", "http://fsp1.uce.cn:8005");

       如果要允许跨域携带cookie,设置响应头Access-Control-Allow-Credentials属性为true
            response.setHeader("Access-Control-Allow-Credentials", "true");

      为了统一响应参数,不用在每个controller中设置响应头。一般通过Filter实现响应头的统一处理

     1 import java.io.IOException;
     2 
     3 import javax.servlet.Filter;
     4 import javax.servlet.FilterChain;
     5 import javax.servlet.FilterConfig;
     6 import javax.servlet.ServletException;
     7 import javax.servlet.ServletRequest;
     8 import javax.servlet.ServletResponse;
     9 import javax.servlet.http.HttpServletResponse;
    10 
    11 public class AccessFilter implements Filter {  
    12   
    13     @Override  
    14     public void init(FilterConfig filterConfig) throws ServletException {  
    15           
    16     }  
    17   
    18     @Override  
    19     public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {  
    20           
    21         HttpServletResponse response = (HttpServletResponse) res;  
    22         response.setHeader("Access-Control-Allow-Origin", "http://fsp1.uce.cn:8005");  
    23         response.setHeader("Access-Control-Allow-Credentials", "true");  
    24         /*response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  
    25         response.setHeader("Access-Control-Max-Age", "3600");  
    26         response.setHeader("Access-Control-Allow-Headers", "x-requested-with");  */
    27         chain.doFilter(req, res);  
    28     }  
    29   
    30     @Override  
    31     public void destroy() {  
    32           
    33     }  
    34   
    35 }  


      这样ajax请求就实现啦可带cookie的跨域交互。

      

      iframe跨域:iframe原生支持跨域。跨域iframe主要难在和父窗口进行数据交互。

        父窗口向跨域iframe传输数据:主要分为postMessage和window.name,postMessage只能在窗口加载完成后才能使用,如果是固定的iframe标签,可直接获取iframe.postMessage,如果是动态添加的iframe必须监听iframe的load事件,在该事件中postMessage。window.name当然也必须在window存在后才能设置,也要设置在iframe的load事件中,但window.name属性有个特点是只要window存在,doument重新roload的时候,window.name是不变的,因此,对于要在iframe加载过程中使用的数据,我们可以先让iframe的window load一次,此次load是一个空白页面,当空白页面load完成事件设置window.name属性,在设置window.name属性后再修改iframe的src让此window重新加载目标跨域页面,这时在该跨域页面加载过程中就个通过window.name获取到父页面传输的数据。

          主要有两种情况:

            1>传输的数据在此跨域iframe加载完成后内部触发事件时使用,可通过postMessage传输,此方法较为简单

            

    var state = 1;
    document.getElementById('#iframeId').addEventListener("load", function() { if(state == 1) { state = 0; this.contentWindow.postMessage(data,crossDomain) } }, true);

             2>传输的数据在此跨域iframe加载过程中调用,此时不能在使用postMessage,该方法只能执行于窗口加载完成后,即load事件后,但在加载过程中如果获取参数,该参数还未传递过来,此时必须使用window.name传递,window的name属性在窗口重新加载内容的时候是不会改变的,最大支持2M。既然要在窗口load时就要读取参数,那么该参数必须要在窗口load之前设置进去,所以要首先load一次窗口,此次load的url为一空白中间页面,目的只是让window加载并且设置window.name属性,在设置之后改变iframe的url为我们的目标跨域url,则iframe从新出发load事件,此时load的过程中就可以获取上次load中间页面设置的window.name属性就获取到了父窗口的值

      跨域iframe向父窗口传递数据“

        此时iframe已经加载完成,使用postMessage比较方便,父窗口监听跨域iframe的messge,进行相应的处理,比如调用自身的函数

        

    window.onload = function() {
        if(window.top == window.self) {
            //当前窗口为最顶层窗口
            return;
        } else {
            //折叠消息面板
            document.body.onclick = function(event) {
                //如果直接调用父页面成功,则直接调用,如果调用失败则为跨域,向父页面传递消息
                try {
                    if(window.top.vm.settings.type) {
                        window.top.vm.openSetting(event);
                    }
                } catch(e) {
                    window.top.postMessage('click', '*');
                }
            }
    
            //皮肤设置
            var settings = localStorage.settings;
            var themes = settings ? JSON.parse(settings) : {
                themes: "default"
            }
            var css = document.createElement('style');
            css.type = 'text/css';
            css.id = "themes-setting";
            if(themes.themes == 'default') {
                css.innerHTML = ".iconfont{color:#ff9372;}";
            } else if(themes.themes == 'blue') {
                css.innerHTML = ".iconfont{color:#23b7e5;}";
            } else {
                css.innerHTML = ".iconfont{color:#464c5b;}";
            }
            document.head.appendChild(css);
        }
    
    }
    /**
                     * 监听跨域iframe传递的消息
                     */
                    window.addEventListener('message', function(e) {
                        var operate = e.data;
                        switch(operate) {
                            case 'click':
                                debugger
                                if(vm.settings.type){
                                    vm.openSetting();
                                }
                                break;
                            default:
                                break;
                        }
    
                    })
  • 相关阅读:
    枚举--分巧克力--蓝桥杯--二分法
    枚举笔记之哈希表 四个平方和
    枚举 蓝桥杯 四个平方数和2--暴力解法 超时
    枚举例题之平方十位数思路无代码
    LeetCode----盛最多水的容器「贪心」
    2020校招笔试
    2020校招美团点评笔试
    2020校招搜狗笔试
    2020网易校招笔试
    2020校招途家名宿开发笔试
  • 原文地址:https://www.cnblogs.com/xj-blog/p/8288857.html
Copyright © 2011-2022 走看看