在開發日常中,會遇到使用iframe嵌套其他頁面,想要與嵌套頁面進行交互,常常會涉及到跨域問題,何為跨域?這涉及到同源策略,即協議、端口、域名相同則為同源
違反了同源策略就會出現跨域問題,主要表現為以下三方面:
1.無法讀取cookie、localStorage、indexDB
2.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...