"長時間不寫文章,開頭的方式老是那麼出奇的類似",最近很忙,很久沒寫博客了啊(是否是?)。
更換工做已經有三個月有餘,這段三個月把過去三年沒加過的班都加了一次。收穫挺多,發現的問題也挺多。
一直也在思考一些問題:
如何把本身碰見的問題好好的理解而且總結?
如何很好的學習新知識,不僅是停留在用的基礎上?
……segmentfault
上面的問題我一直在嘗試更適合個人方法,暫時就不扯淡了,先嚐試一下把這段時間過程當中碰見的問題總結下,而後爭取給看文的你以個人方式描述清楚,我想我應該就把第一個問題解決了。跨域
項目實戰中postMessage
的使用app
前提:咱們的項目與兄弟團隊的項目都是基於同一套基礎框架開發,只是在視圖層咱們有各自的一套東西。
項目是一個hybrid項目,目前是以h5的形式在開發,後期能夠輕鬆轉爲hybrid。目前已經以h5的形式上線到自家公衆號,大體是在硬件上產出一份報告,h5把報告的內容展現出來。
新需求是,把報告推給兄弟團隊的APP,在APP內也能打開咱們的報告進行查看報告而後點評。
兄弟團隊爲了最小的改動實現這個功能,用了iframe的形式打開咱們推過去的報告連接,問題就出在報告能在兄弟團隊的APP中打開卻不能跳轉連接,問題是由於咱們的基礎框架提供的forward
方法在app內是經過native的方式來跳轉,可是咱們的協議不會被兄弟團隊的app識別,簡單說就是跳轉直接被攔截了。
通過幾番商量,商定出三個解決方案:框架
很明顯咱們更傾向於第一種方式,彷彿記得以前總結過相似的一篇文章同源策略和跨域知識點學習,當時徹底是參考知識點進行的一次搬移,如今看來徹底仍是沒有透徹理解。post
postMessage
派上用途。
h5模式下子頁面跳轉協議能夠正常使用history模式或者非單頁模式跳轉。(知識點:這種狀況下iframe的src不會隨iframe內跳轉連接的變化而變化,父頁面不能監聽到子頁面內的頁面變化)
hybrid模式下連接跳轉被攔截,頁面表現就是連接點不了,如何讓父元素知道我點了什麼連接,而後來切換頁面,他們作url更換,來實現跳轉而且支持切換頁面操做,如此咱們就須要子頁面給父頁面發送一條message
告訴它我要跳轉到哪個頁面。學習
頁面跳轉中咱們使用了$forward
方法進行收口,全部的跳轉都須要通過這個方法(對於收口的好處這裏就體現出來了),我只須要判斷ua
在跳轉前執行如下消息發送的方法。this
/** * 頁面跳轉方法 * @param page 要跳轉的頁面名稱 * @param param 跳轉時須要額外攜帶的參數 */ $forward(page, param) { // _ extend getUrlParam getUrlRule loadPage isHybrid 省略 var param = _.extend(_.getUrlParam(), param); let url = _.getUrlRule(page, param); if(isHybrid) { _.requestHybrid({ // 省略 }); } else { _.loadPage(url); } }
在跳轉前咱們先檢測一下ua
,判斷是不是在兄弟團隊app內作特殊處理url
let ua = navigator.userAgent.toLowerCase(), isFriendHybrid = /friend_hybrid_\w+_(\d*\.?)+/.test(ua); if(isFriendHybrid) { window.top.postMessage({ tag: 'forward', url: url }, '*') } else { this.$forward(); }
在兄弟團隊的父頁面只須要監聽message
事件獲取我傳遞過去的消息作特殊處理便可.net
window.addEventListener('message', function(e) { console.log(e.data); // {tag: 'forward', url: ……} })
例如在一個特殊位置我會在沒有pdf的時候直接彈出調試「暫時沒有報告」,用戶點擊之際顯示的是我彈出的toast,因爲嵌入後有兼容問題,因而咱們又約定了一個方法。調試
window.top.postMessage({ tag: 'showtoast', content: '暫時沒有報告' }, '*')
這應該就是一個典型的iframe跨域通訊例子。
https://jsfiddle.net/unofficial/xwaksbvn/