封裝一個postMessage庫,進行iframe跨域交互
- 2021 年 3 月 30 日
- 筆記
- postMessage, 前端, 前端筆記
這是近期個人在開發chrome插件時的其中一個小總結。還有很多沒有總結出來。因為目前插件還在迭代中,(herry菌插件,用於B站C站),屬於個人業餘的一個小項目。還有很多功能沒有實現,以及還需要再看能加上什麼功能。
封裝的postMessage庫 herryPostMessage.js
(function (w) { //herry對象 w.herry = {}; //iframe的id if(!herry.iframeId) { herry.iframeId = 'iframe' } //父窗口名字 if(!herry.parentName) { herry.parentName = '父窗口' } //子窗口名字 if(!herry.childName) { herry.childName = '子窗口' } //跨域對象 const messageObj = {}; //父頁面 /** * 發送給子頁面數據 */ const postMessage = (data, fn = null) => { const iframe = document.getElementById(herry.iframeId) iframe.contentWindow.postMessage( { name: herry.parentName, //父頁面名字 ...data, }, "*" ); messageObj[data.action] = fn; }; /** * 監聽子頁面返回的數據 */ w.addEventListener( "message", (event) => { const { data } = event; if (data && typeof data === "object" && data.name === herry.childName) { messageObj[data.action](data); } }, false ); //子頁面 /** * 返回數據給父頁面 參1=當前action 參2=返回的數據 */ const returnData = (action, data) => { top.postMessage( { name: herry.childName, //子頁面名字 action, data, }, "*" ); }; /** * 監聽父頁面發送的數據 */ w.addEventListener( "message", async (event) => { const { data } = event; if (data && typeof data === "object" && data.name === herry.parentName) { if (herry.callback) { herry.callback(data) } } }, false ); herry.postMessage = postMessage; herry.returnData = returnData; })(window);
使用這個庫讓a域名下獲取b域名下的數據,即a發出請求,b返回給a數據。a是父頁面,b是子頁面
使用:
域名a和b的頁面上都需要引入herryPostMessage.js
a頁面處理(父頁面):
加入iframe(src是b域名的頁面,需要設置一個id,一般也可以將iframe使用樣式隱藏掉)。
<iframe src="//b.com/xxx.html" id="ifr" frameborder="0" ></iframe>
設置iframeId=上面的這個id:
herry.iframeId = "ifr";
發起請求(action是設置的一個請求名,在b頁面中進行匹配用。後面的數據是攜帶給b頁面用的參數。後面的res是b頁面執行後的回調函數,可進行處理b返回的數據):
herry.postMessage({ action:'geta1', x: 1 }, (res) => {
console.log(res.data);
});
b頁面處理(子頁面):
b頁面的herry.callback通過action匹配執行,並做處理,通過herry.returnData將數據返回給a的回調函數。即實現了交互。
herry.callback = async (data) => { if (data.action === "geta1") { //... herry.returnData(data.action, { x: 2 }); } //... };
不過這種封裝方式也不是特別好,有局限性,比如b(子頁面)像a(父頁面)發起請求還是比較麻煩。歡迎各位提出意見或建議。