iframe 元素跨域訪問

admin發表於2019-07-23

使用<iframe>元素可以在當前頁面嵌入其他頁面。

如果兩個頁面是不同源的,那麼父子視窗無法通訊,也就是無法拿到對方的DOM。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
document.getElementById("theIframe").contentWindow.document

如果父子視窗非同源,那麼上面程式碼會報錯;對於window.open方法開啟的視窗也是如此。

如果兩個視窗一級域名相同,那麼只要將document.domain屬性值設定為根域名即可:

[JavaScript] 純文字檢視 複製程式碼
document.domain = 'softwhy.com';

關於document.domain可以參閱JavaScript 跨域訪問cookie一章節。

對於根域名不同頁面,可以使用如下兩種方式解決跨域視窗的通訊問題:

一.通過錨點傳遞資訊:

關於錨點可以參閱HTML 錨點定位一章節,以如下連結為例子:

[HTML] 純文字檢視 複製程式碼
http://www.softwhy.com/antzone.html#ts

只改變錨點不會不會重新重新整理網頁,父視窗可以通過這個錨點來傳遞資訊:

[JavaScript] 純文字檢視 複製程式碼
let src = iframeURL + "#" + data;
document.getElementById("theiframe").src = src;

這樣我們就將資料通過data傳遞給了iframe子頁面。

然後通過hashchange事件來進行監聽錨點資訊的變化,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
window.onhashchange = handler;
function handler() {
  let data = window.location.hash;
}

相同的道理,子視窗也可以改變父視窗的錨點:

[JavaScript] 純文字檢視 複製程式碼
parent.location.href= target + "#" + hash;

二.window.postMessage()方法:

H5ML5引入了window.postMessage()可以實現跨視窗通訊,並且不受同源策略的限制。

程式碼片段如下:

[JavaScript] 純文字檢視 複製程式碼
var popup = window.open("http://b.com","title");
popup.postMessage("螞蟻部落","http://b.com");

在http://a.com中執行上述程式碼,會開啟一個新的http://b.com視窗,然後傳遞一個字串"螞蟻部落"。

關於postMessage()方法參閱postMessage() 方法一章節。

子視窗向父視窗傳送資訊也是同樣的道理:

[JavaScript] 純文字檢視 複製程式碼
window.opener.postMessage("父視窗你好", "http://a.com");

上面已經傳遞了資訊,自然要通過一定的手段來監聽和獲取這些資訊:

[JavaScript] 純文字檢視 複製程式碼
window.addEventListener("message", function(event) {
  console.log(event.data);
},false);

關於message事件更多內容參閱message 事件一章節。

相關文章