4

In daily development, you will encounter nesting other pages using iframes. If you want to interact with nested pages, cross-domain issues are often involved. What is cross-domain? This involves the same-origin policy, that is, if the protocol, port, and domain name are the same, the same-origin

Violation of the same-origin policy will cause cross-domain problems, mainly in the following three aspects:
1. Unable to read cookies, localStorage, indexDB
2. The DOM cannot be obtained
3. Ajax request cannot be sent

Solution

First, set the domain

Prerequisite: These two domain names must belong to the same basic domain name! And the protocols and ports used must be the same, otherwise document.domain cannot be used for cross-domain

Implementation:

 //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>

Phenomenon : Loading a.html will print "demo"
Reason analysis : When the main domains communicate with each other, as long as the document.domain of the two is assigned as the current main domain address, cross-domain communication can be realized.

2. Use the middle page

You can also use a page c with the same domain name as page a but a different route as an intermediate page, page b loads page c, and page c calls the method of page a, so as to realize the method of page b calling page a. The specific operations are as follows:
A new route is opened at the node layer of the a page. This route loads a c page as an intermediate page, and the url of the c page is a.demo.com/c. The c page is just a simple html page, and the method of the a page is called on the onload event of the window.

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

Three, postmessage

The window.postMessage() method allows scripts from one document to pass text messages to scripts in another document, regardless of whether they are cross-domain or not. Scripts in one document still cannot call methods and read properties in other documents, but they can communicate securely using this messaging technique.

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>

During the actual use of this method, window.addEventListener() was triggered before the DOM of b.html was loaded, and no data was received in b.html, so a timer was added in a.html

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

The iframe cross-domain problem can be solved by the above methods. If there is any error, please correct the reference source: https://juejin.cn/post/6844903831973675015


mosquito
7 声望4 粉丝

记录工作中遇到的问题