iframe跨域操作dom

1,387 阅读1分钟

iframe跨域操作

域名跨域情况

域名A域名B是否跨域
http://localhost/ahttp://localhost/b
http://localhost/http://localhost/是,协议不一样
a.localhost/b.localhost/是,域名不一样
http://localhost:80/http://localhost:8080/是,端口不一样

A 页面

    <h1>页面 A</h1>
    <input type="text" />
    <div>
        <iframe id="ifr" src="http://localhost:3002/index.html" frameborder="0"></iframe>
    </div>

    <script>
        document.domain = 'http://localhost';

        window.onload = function () {
            var iframeWin = ifr.contentWindow;
            const iframeDoc = iframeWin.document;
            console.log('iframeWin', iframeWin, iframeDoc);
            iframeDoc.getElementById('input').value = '777';
            iframeWin.test();
        };
    </script>

B 页面

    <h2>页面B</h2>
    <input id="input" type="text">
    <button type="button">刷新</button>

    <script>
        document.domain = 'http://localhost';
        document.querySelector('button').addEventListener('click', function(){
            location.reload();
        })

        function test() {
            console.log('test');
        }
    </script>

一、document.domain 方案

示例

A页面
localhost:3000
do

B页面
localhost:3002

此时把两个页面的document.domain = 'localhost'

注意: 1.domain设置的不需要带前面的“http://” 2. 访问iframe元素需要在window.onload中 3. 使用于二级域名

二、Postmessage 方案

A页面
const btn = document.querySelector('button');
btn.addEventListener('click', function(){
    const iframeWin = ifr.contentWindow;
    const message = JSON.stringify({
        "test": "测试"
    });
    const targetOrigin = 'http://localhost:3002';
    iframeWin.postMessage(message, targetOrigin);
}, false);
B 页面
window.addEventListener('message', handle, false);
function handle (e) {

}

三、window.name方案 创建一个iframe,加载跨域页面,然后设置成同域页面。因为域名变了window.name不会变, 跨域页面的windows.name依然保留,就可以获取到window.name值。

A 页面
var otherLoaded = false,
    iframe = document.createElement('iframe'),
    loadfn = function () {
        if (otherLoaded) {
            var data = iframe.contentWindow.name; // 读取数据
            // alert(data); // 弹出b.html's data
            console.log(data);

            // 清理工作
            iframe.contentWindow.document.write('');
            iframe.contentWindow.close();
            document.body.removeChild(iframe);
        } else if (!otherLoaded) {
            otherLoaded = true;
            iframe.contentWindow.location = 'http://localhost:3000/proxy.html'; // 设置的代理文件
        }
    };
    
iframe.src = 'http://localhost:3002/name-2.html';
if (iframe.attachEvent) {
    iframe.attachEvent('onload', loadfn);
} else {
    iframe.onload = loadfn;
}
iframe.style.visibility = 'hidden'
document.body.appendChild(iframe);
B 页面
window.name = "页面:data";

四、hash方案 给url添加hash,不会刷新页面。父给子iframe的src添加hash,子页面监听hash的变化,达到传值的效果。

A 页面
 <iframe id="ifr" src="http://localhost:3002/hash-2.html" frameborder="0"></iframe>

const btn = document.querySelector('button');
const src = ifr.src;
let i = 0;
btn.addEventListener('click', function(){
    ifr.src = src + '#' + 'test=测试'+ (i++)
}, false);

B 页面
function handle (e) {
            const msg = location.hash;
            console.log('hash', decodeURI(msg));
        }

        window.addEventListener('hashchange', handle, false);