Cross-domain solution (detailed)

window.name+iframe.contentWindow.name

There are three pages:

  • a.com/app.html: The application page.
  • a.com/proxy.html: The proxy file, generally an html file without any content, needs to be in the same domain as the application page.
  • b.com/data.html: The page where the application page needs to obtain data, which can be called the data page.

The basic steps to achieve it are as follows:

  1. Create an iframe in the app page (a.com/app.html) and point its src to the data page (b.com/data.html).
    The data page will append the data to the window.name of this iframe. The data.html code is as follows:
    <script type="text/javascript">
        window.name = 'I was there!'; // Here is the data to be transmitted, the size is generally 2M, and it can be as large as 32M under IE and firefox
                                         // The data format can be customized, such as json, string
    </script>
  2. Listen to the onload event of the iframe in the application page (a.com/app.html), and set the src of the iframe in this event to point to the proxy file of the local domain (the proxy file and the application page are in the same domain, so they can communicate with each other) . Part of the code in app.html is as follows:
    <script type="text/javascript">
        var state = 0,
        iframe = document.createElement('iframe'),
        loadfn = function() {
            if (state === 1) {
                var data = iframe.contentWindow.name; // read data
                alert(data);    //弹出'I was there!'
            } else if (state === 0) {
                state = 1;
                iframe.contentWindow.location = "http://a.com/proxy.html"; // set proxy file
            }  
        };
        iframe.src = 'http://b.com/data.html';
        if (iframe.attachEvent) {
            iframe.attachEvent('onload', loadfn);
        } else {
            iframe.onload  = loadfn;
        }
        document.body.appendChild(iframe);
    </script>
  3. After obtaining the data, destroy the iframe and release the memory; this also ensures security (not accessed by other domain frame js).
    <script type="text/javascript">
        iframe.contentWindow.document.write('');
        iframe.contentWindow.close();
        document.body.removeChild(iframe);
    </script>

To sum up, the src attribute of the iframe is transferred from the external domain to the local domain, and the cross-domain data is passed from the external domain to the local domain by the iframe's window.name. This cleverly bypasses the browser's cross-domain access restrictions, but at the same time it is a safe operation.

postMessage跨域
postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:
a.) 页面和其打开的新窗口的数据传递
b.) 多窗口之间消息传递
c.) 页面与嵌套的iframe消息传递
d.) 上面三个场景的跨域数据传递

用法:postMessage(data,origin)方法接受两个参数
data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

1.)a.html:(http://www.domain1.com/a.html)
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>       
    var iframe = document.getElementById('iframe');
    iframe.onload = function() {
        var data = {
            name: 'aym'
        };
        // 向domain2传送跨域数据
        iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
    };
    // 接受domain2返回数据
    window.addEventListener('message', function(e) {
        alert('data from domain2 ---> ' + e.data);
    }, false);

</script>


2.)b.html:(http://www.domain2.com/b.html)
<script>
    // 接收domain1的数据
    window.addEventListener('message', function(e) {
        alert('data from domain1 ---> ' + e.data);
        var data = JSON.parse(e.data);
        if (data) {
            data.number = 16;
            // 处理后再发回domain1
            window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
        }
    }, false);
</script>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324770202&siteId=291194637