这里演示一个容器端和嵌入端跨域iframe通信的思路:
原理就是利用两端监听message事件,然后通过向对方发送postMessage进行双向通信。
难点在于当第一次加载时,嵌入端如何无延时的获取容器端的数据。
源码如下:
// 嵌入端: class messager { clientList = {} constructor() { this.onMessage(); } listen(key, fn) { this.clientList[key] = fn; } trigger(key, data) { this.clientList[key](data); } onMessage() { window.addEventListener( "message", (event) => { switch(event.data.code) { case '8001': this.trigger('message', event.data); break; default: console.error('暂时不支持这个消息!'); } }, false ); } sendMessage(iframeWindow, message, origin, callback) { this.listen('message', callback); iframeWindow.postMessage(message, origin); } } Vue.prototype.$message = new messager();
// 容器端: class messager { clientList = {} constructor() { this.onMessage(); } listen(key, fn) { this.clientList[key] = fn; } trigger(key, data) { this.clientList[key](data); } onMessage() { window.addEventListener( "message", (event) => { switch(event.data.code) { case '8001': const serverList = JSON.parse(localStorage.getItem('UrlConfig')); const token = { loginToken: JSON.parse(localStorage.getItem('AccountToken')), oaToken: JSON.parse(localStorage.getItem('OA_Server')) }; const userInfo = JSON.parse(localStorage.getItem('userInfo')); this.sendMessage(document.getElementById('businessIframe').contentWindow, {code: '8001',serverList, token, userInfo}, '*'); break; case '8002': window.history.back(); console.log('路由回退:', event.data.message); break; default: console.error('暂时不支持这个消息!'); } }, false ); } sendMessage(iframeWindow, message, origin) { iframeWindow.postMessage(message, origin); } } window.$message = new messager();
评论区