一、获取句柄 + postMessage 必须有一个页面(如A页面)可以获取另一个页面(如B页面)的window对象,这样才可以完成通信
1 2 3 4 5 6 7 8 9 10 11 const childPage = window .open('child.html' , 'child' )childPage.onload = () => { childPage.postMessage('hello' , location.origin) } window .onmessage = evt => { }
二、localStorage + storageEvent 同源的两个tab页面可以通过共享localStorage的方式通信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 window .addEventListener("storage" , function (ev ) { if (ev.key == 'message' ) { if (!ev.newValue) return ; var message = JSON .parse(ev.newValue); console .log(message); } }); function sendMessage (message ) { localStorage.setItem('message' ,JSON .stringify(message)); localStorage.removeItem('message' ); } sendMessage('this is message from A' );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 B 页面 window .addEventListener("storage" , function (ev ) { if (ev.key == 'message' ) { if (!ev.newValue) return ; var message = JSON .parse(ev.newValue); sendMessage('message echo from B' ); } }); function sendMessage (message ) { localStorage.setItem('message' ,JSON .stringify(message)); localStorage.removeItem('message' ); }
三、iframe + postMessage 通过在这两个tab页嵌入同一个iframe页实现“桥接”,最终完成两个不相关的tab页通信
1 2 3 4 5 tab A -----> iframe A[bridge.html] | | \|/ iframe B[bridge.html] -----> tab B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 window .sendMessageToTab = function (data ) { document .querySelector('#J_bridge' ).contentWindow.postMessage(JSON .stringify(data),'/' ); }; window .addEventListener('message' ,function (e ) { let {data,source,origin} = e; if (!data) return ; try { let info = JSON .parse(JSON .parse(data)); if (info.type == 'BSays' ){ console .log('BSay:' ,info); } }catch (e){ } }); sendMessageToTab({ type: 'ASays' , data: 'hello world, B' })
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 window .addEventListener("storage" , function (ev ) { if (ev.key == 'message' ) { window .parent.postMessage(ev.newValue,'*' ); } }); function message_broadcast (message ) { localStorage.setItem('message' ,JSON .stringify(message)); localStorage.removeItem('message' ); } window .addEventListener('message' ,function (e ) { let {data,source,origin} = e; message_broadcast(data); });
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 window .addEventListener('message' ,function (e ) { let {data,source,origin} = e; if (!data) return ; let info = JSON .parse(JSON .parse(data)); if (info.type == 'ASays' ){ document .querySelector('#J_bridge' ).contentWindow.postMessage(JSON .stringify({ type: 'BSays' , data: 'hello world echo from B' }),'*' ); } }); document .querySelector('button' ).addEventListener('click' ,function ( ) { document .querySelector('#J_bridge' ).contentWindow.postMessage(JSON .stringify({ type: 'BSays' , data: 'I am B' }),'*' ); })
参考:
跨浏览器tab页的通信解决方案尝试
跨页面通信的各种姿势