网络日志

iframe跨域的几种常用方法

在开发日常中,会遇到使用iframe嵌套其他页面,想要与嵌套页面进行交互,常常会涉及到跨域问题,何为跨域?这涉及到同源策略,即协议、端口、域名相同则为同源

违反了同源策略就会出现跨域问题,主要表现为以下三方面:1.无法读取cookie、localStorage、indexDB2.DOM无法获得3.ajax请求无法发送

解决方法

一、设置domain

前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域

具体实现:

//a.html
 <iframe src="http://b.demo.com:8080/b.html" "load()" id="frame"></iframe>
 <script type="text/javascript">
   document.domain = 'demo.com';
   function load(){
    console.log(frame.contentWindow.name);
   }
 </script>

 //b.html
 <script type="text/javascript">
  document.domain = 'demo.com';
  var name = 'demo';
 </script>

现象:加载a.html,会打印"demo"原因分析:当主域之间相互通信的时候,只要将两者的document.domain赋值为当前的主域地址,即可实现跨域通信。

二、使用中间页面

还可以使用一个与a页面同域名但不同路由的c页面作为中间页面,b页面加载c页面,c页面调用a页面的方法,从而实现b页面调用a页面的方法。具体操作如下:在a页面的node层新开一个路由,此路由加载一个c页面作为中间页面,c页面的url为a.demo.com/c。c页面只是一个简单的html页面,在window的onload事件上调用了a页面的方法。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <script>
        window.onload = function () {
            console.log()
        }
    </script>
</body>
</html>

三、postmessage

window.postMessage() 方法允许来自一个文档的脚本可以传递文本消息到另一个文档里的脚本,而不用管是否跨域。一个文档里的脚本还是不能调用在其他文档里方法和读取属性,但他们可以用这种消息传递技术来实现安全的通信。

a.html:

<body>
    <button onclick="postTestMessage()">postMessage</button> 
   <iframe src="./b.html" frameborder="0" id="iframe"></iframe> 
</body>
<script>
    let receiveMessage = function(event) {
        console.log('a: ', event);
        let datas = JSON.parse(event.data);
        if (datas.type === "advert") {
                let postIframeData = {
                        type:'adGivePrize',
                        givePrize:true
                };
                //iframe发送信息~~~~
                window.frames[0].postMessage(JSON.stringify(postIframeData), '*');
                // window.frames[0].postMessage('a页面', '*');
        }
    }

    window.addEventListener("message", receiveMessage, false);

    function postTestMessage() {
        let defaultAdData = {
                    type:'advert', 
                    gameData:{
                        adId: '123'
                    }
            };
        window.postMessage(JSON.stringify(defaultAdData), '*');
    }
</script>

b.html

<body>
    <h1>我是b页面</h1>
</body>
<script>
var receiveMessage = function(event) {
    console.log('b: ', JSON.parse(event.data));
}
window.addEventListener("message", receiveMessage, false);
</script>

在实际使用此方法的过程中遇到了b.html的DOM未加载完就触发了window.addEventListener(),在b.html接收不到数据,因此在a.html中加了定时器

// 定时访问发送信息,在iframe页面在没加载完页面触发了addEventListener方法,获取不到数据
         let count = 0;
     that.timer = setInterval(() => {
       postTestMessage();
       count++;
       if (count > 10) {
         clearInterval(that.timer);
       }
     }, 500);

通过以上方法可以解决iframe跨域问题啦~有错误欢迎指正参考来源:https://juejin.cn/post/684490...