当前位置:首页 > 前端解决跨域的常用方法之js 跨域复习 window.name | window.domain | iframe | Jsonp

前端解决跨域的常用方法之js 跨域复习 window.name | window.domain | iframe | Jsonp

发布于 2018-04-11 阅读 381 次 Javascript HTML5

引起跨域的原因:

浏览器的同源策略,但是当你要发送请求的时候,出于安全性问题,浏览器有严格的要求,必须协议,域名,端口都相同,这个就是同源策略。
影响:a通过js脚本向b发送ajax请求,不同源就会报错
不受影响:script标签,img标签等外部资源引用,重定向,表单提交都不受影响

iframe遇到的跨域问题

情况一、

假设有a.com/main.html ; a.com/b.html
这种情况是涉及不到跨域的

main.html代码:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div class="box">
        <iframe id="if" src="b.html" frameborder="0"></iframe>
    </div>
<script>
    //获取b的数据
    var bdoc = window.frames[0].document;
    //通过bdoc做操作
</script>
</body>
</html>

b.html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <input id="message" type="text" />
    <script>
                //获取父窗docuemnt
        var pdoc = parent.document;
    </script>
</body>
</html>

情况二、

假设有a.com/main.html ; b.a.com/b.html 此时主域相同子域不同

只需要在两个页面同时显式的设置docuement.domian = “a.com”即可

情况三、

主域不同 假设有页面 a.com/main.html ; a.com/blank.html ; b.com/b.html
此时可以利用window.name实现消息传递,具体做法如下:

b.html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <input id="message" type="text" />
    <script>
         window.name = "我是要传递的消息";
        </script>
</body>
</html>

a.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div class="box">
        <iframe id="if" src="b.com/b.html" frameborder="0"></iframe>
    </div>
<script>
    var fr = document.getElementById('if'),
        state = 0;;
        if(window.VBArray){//兼容ie
            fr.onreadystatechange = function(){
                if(this.readyState == 'complete'){
                    if(state == 1){
                        // 获取数据
                        data = fr.contentWindow.name;
                    }else{
                        state = 1;
                        // 重置iframe窗口的src保证同源
                        fr.src = 'a.com/blank.html';
                    }
                }
            }
        }else{
            fr.addEventListener('onload',function(){
                if(state == 1){
                    // 获取数据
                    data = fr.contentWindow.name;
                }else{
                    state = 1;
                    // 重置iframe窗口的src保证同源
                    fr.src = 'a.com/blank.html';
                }
            },false);
        }
</script>
</body>
</html>

注意:window.name最大存储2M,只能存储字符串格式。由于此方法会重新加载空页面作为iframe的源,所以只适用于隐藏iframe的情况

还有一种方式通过document.hash

由父窗口修改子窗口的src添加hash,hash就是要传递的数据,修改hash不会导致页面刷新,子窗口通过一个定时器,定时检测hash是否变化,从而获取父窗口给的数据。