iframe跨域操作
域名跨域情况
| 域名A | 域名B | 是否跨域 |
|---|---|---|
| http://localhost/a | http://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);