這是近期我的在開發chrome插件時的其中一個小總結。還有不少沒有總結出來。由於目前插件還在迭代中,(herry菌插件,用於B站C站),屬於我的業餘的一個小項目。還有不少功能沒有實現,以及還須要再看能加上什麼功能。html
封裝的postMessage庫 herryPostMessage.jschrome
(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是子頁面跨域
使用:async
域名a和b的頁面上都須要引入herryPostMessage.js函數
加入iframe(src是b域名的頁面,須要設置一個id,通常也能夠將iframe使用樣式隱藏掉)。post
<iframe src="//b.com/xxx.html" id="ifr" frameborder="0" ></iframe>
設置iframeId=上面的這個id:spa
herry.iframeId = "ifr";
發起請求(action是設置的一個請求名,在b頁面中進行匹配用。後面的數據是攜帶給b頁面用的參數。後面的res是b頁面執行後的回調函數,可進行處理b返回的數據):插件
herry.postMessage({ action:'geta1', x: 1 }, (res) => {
console.log(res.data);
});
b頁面的herry.callback經過action匹配執行,並作處理,經過herry.returnData將數據返回給a的回調函數。即實現了交互。code
herry.callback = async (data) => { if (data.action === "geta1") { //... herry.returnData(data.action, { x: 2 }); } //... };
不過這種封裝方式也不是特別好,有侷限性,好比b(子頁面)像a(父頁面)發起請求仍是比較麻煩。歡迎各位提出意見或建議。htm