iframe+postMessage實現跨域通訊

前言

需求背景:

最近開發管理系統,須要在本頁面跳轉到一個圖片管理系統上傳圖片,上傳成功後返回圖片連接,而後返回管理系統,顯示圖片算法

實現思路:

  1. 上傳圖片時,須要在本窗口跳轉到圖片管理系統,而且兩個系統之間要通訊
  2. 考慮到兩個系統是不一樣的端口號,存在跨域問題,這時發現HTML5新增了一個API-window.postMessage(),因而就決定用iframe結合window.postMessage()實現
  3. 在頁面中嵌入一個iframe,將圖片管理系統嵌入到當前的管理系統中,結合window.postMessage()實現跨域通訊

項目背景

  • 該管理系統基於React.js搭建,在此簡稱爲A頁面,地址爲http://www.blogoog.com:8000
  • 圖片管理系統基於Vue.js搭建,在此簡稱爲B頁面,地址爲http://www.blogoog.com:8088

具體實現

參考資料

一、A頁面使用到的語法

window.postMessage()

otherWindow.postMessage(message, targetOrigin, [transfer]);
  • otherWindow:其餘窗口的一個引用(在這裏我使用了iframe的contentWindow屬性)
  • message:將要發送到其餘window的數據(能夠不受限制的將數據對象安全的傳送給目標窗口而無需本身序列化,緣由是由於採用了結構化克隆算法
  • targetOrigin:接收信息的URL(在這裏我固然填的B頁面的URL)
  • transfer:可選參數(在這裏我沒使用)

具體參考:window.postMessage()-MDN跨域

window.addEventListener('message', receiveMessage, false);

target.addEventListener(type, listener, options);
  • type:表示監聽事件類型的字符串
  • listener:當所監聽的事件類型觸發時,會通知的一個對象或者一個函數
  • potions:可選參數(在此我用false,表示在listener被調用以後不會自動移除)

具體參考:addEventListener-MDN安全

receiveMessage = (event) => {}

  • event.data:從另外一個window傳遞過來的對象(包含傳遞過來的全部信息)
  • event.origin||event.originalEvent.origin:window.postMessage()發送消息的目標URL
  • event.source:對發送消息的窗口對象的引用

注意點!!!

  • 在頁面內嵌入iframe頁面的狀況下,須要等到頁面內的iframe頁面,也就是B頁面加載完成以後,才能進行postMessage跨域通訊
  • event.origin中的origin不能保證是該窗口的當前origin或者將來origin,由於postMessage被調用後,可能會被導航到不一樣的位置,因此須要作個異常狀況判斷處理origin !== 'http://www.blogoog.com:8088'

二、B頁面使用到的語法

top.postMessage('data', 'http://www.blogoog.com:8000')

  • 參考上面A頁面的語法
  • 爲何用top而不用window下面再講

window.addEventListener('message', receiveMessage, false);

  • 參考上面A頁面的語法

receiveMessage = (event) => {}

  • 參考上面A頁面的語法

window.postMessage()中的window究竟是啥?

始終是你須要通訊的目標窗口ide

  • A頁面中:A頁面向B頁面發送跨域信息,window就是在A頁面中嵌入的iframe指向的B頁面的window,即:iframe.contentWindow
  • B頁面中:B頁面想A頁面發送跨域信息,window就是A頁面的window,在這裏由於B頁面時嵌入到A頁面中的,對於B頁面來說,window就是top或者parent

須要特別注意的坑

  1. 必定要等A頁面嵌入的B頁面加載完成以後,再進行postMessage跨域通訊
  2. 必定要對origin作判斷,去掉不是來自咱們目標窗口的origin,防止來自其餘origin的攻擊
  3. 着重注意window.postMessage()中window的用法,明確目標窗口的window

獻上代碼

A頁面


B頁面

個人博客即將搬運同步至騰訊雲+社區,邀請你們一同入駐:https://cloud.tencent.com/dev...函數

相關文章
相關標籤/搜索