有的時候iframe的子頁面會動態的切換頁面,我們在父頁面通過iframe1.contentWindow.window.location只能獲取同源的子頁面的信息。獲取跨域的子頁面信息會報錯。
這時可以通過html5 提供的接口 postMessage來過去跨域子頁面信息。如下代碼:
在localhost:8000服務器下的入口測試頁面:http://localhost:8000/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 id="title"></h1>
<h1 id="title_1"></h1>
</body>
<script>
window.addEventListener('message',function(rs){
console.log(rs.data);
document.querySelector("#title").innerHTML = rs.data;
});
var iframe = document.createElement("iframe");
document.querySelector("body").appendChild(iframe);
iframe.setAttribute("src","http://localhost:3000/iframe.html");
//iframe.style.display = "none";
//利用contentWindow.window獲取子頁面地址
/*setTimeout(function () {
document.querySelector("#title_1").innerHTML = iframe.contentWindow.window.location;
},1000)*/
</script>
</html>
在localhost:3000服務器下的iframe頁面:http://localhost:3000/iframe.html
這里頁面會自動跳轉到iframe_change.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h2>這是iframe里面的內容</h2>
</body>
<script>
window.location.href = "./iframe_change.html";
</script>
</html>
在localhost:3000服務器下的iframe_change頁面:http://localhost:3000/iframe_change.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>iframe already changed</h2>
</body>
<script>
window.parent.postMessage(window.location.href,"*");
</script>
</html>
這里調用postMessage發送子頁面信息。在index頁面通過以下代碼來獲取子頁面信息。
window.addEventListener('message',function(rs){
console.log(rs.data);
document.querySelector("#title").innerHTML = rs.data;
});
上面的跨域獲取iframe動態url的方法可以實現一個微信web開發中一個很重要的問題:
主頁面利用https://open.weixin.qq.com/connect/oauth2/authorize獲取微信用戶信息,主頁面的域名是有限制的,需要在公眾平台上配置而且一般配置成線上的域名。
但是在實際本地開發的時候,我們主頁面的ip一般是localhost或者192.168.1.198:8080,這在微信瀏覽器上獲取用戶信息的時候會被拒絕,給開發調試造成極大的不便。
利用上面的iframe的方法就可以繞過域名限制的問題:將獲取openId的功能交給單獨的一個頁面
getOpenId.html負責跳轉到微信auth頁面授權獲取code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>授權</title>
<script>
function getUrlParam(name){
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURIComponent(r[2].replace(/%20/g,"+")); return null;
}
var companyAppId = "wx124345678"; //公司自己的appid
var wxCode = getUrlParam('code');
//如果url上沒有code,則跳轉授權
if(!wxCode){
var url = window.location.href;
window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?' +
'appid='+companyAppId+'&redirect_uri='+encodeURIComponent(url)+
'&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect';
}else {
//如果url上有code,則說明已經授權完畢可以返回code給主頁面
window.parent.postMessage(wxCode,"*");
}
</script>
</head>
<body>
</body>
</html>
getOpenId.js 在不影響文檔流的情況下頁面插入iframe進行微信授權,一旦獲取到code,則移除iframe。
var wxTool = {
getOpenId:function (src,callback) {
var iframe = document.createElement("iframe");
iframe.style.display = "none";
document.querySelector("body").appendChild(iframe);
iframe.setAttribute("src",src);
window.addEventListener('message',function(rs){
console.log(rs.data);
callback(rs.data);
iframe.remove();
});
}
};
index.html
wxTool.getOpenId("http://live.domain.com/getOpenId.html",function (code) {
//TODO 利用code請求服務器 獲取微信用戶信息
})
總結:這種方法也許不是最快的,直接在入口頁面的<head>下面寫上<script>直接跳轉進行微信授權然后重定向回來也許是最快的,但是一旦在跳轉授權時由於網絡原因可能導致頁面會出現短暫的空白,這種情況用戶是不願看到的。而利用iframe的好處是它是異步的,不影響主業務的加載和運行。
所以如果你是希望在初始頁面很快的呈現微信用戶的信息則用上面第一種方法,否則,使用iframe可能更好些。
