关于浏览器跨页面通信
浏览器跨页面通信,现在大概有2种方法:
1.Broadcast Channel
同源访问,更加安全,必须放在http服务器上才可通讯。
主页面:index.html
<div><button onclick="postMessage(1)">按钮1</button><button onclick="postMessage(2)">按钮2</button><button onclick="postMessage(3)">按钮3</button><span style="color:#000000;"id="time">等待刷新</span></div><div><iframe style="width:600px;height:600px;"src="./frame.html"frameborder="0"></iframe></div>constbroadcast=newBroadcastChannel('Broadcast');//订阅消息broadcast.onmessage=(msg)=>{console.log("主页面 onmessage:",msg.data);document.getElementById("time").innerHTML=msg.data;}constpostMessage=(msg)=>{console.log("主页面 postMessage:",msg);broadcast.postMessage(msg)}内嵌页面: iframe.html
<div id="content"style="width:500px;height:300px;background-color: pink;">等待主页面广播<button onclick="refreshTime()">刷新主页面时间</button></div>constbroadcast=newBroadcastChannel('Broadcast');//订阅消息broadcast.onmessage=(msg)=>{console.log("内嵌页面 onmessage:",msg.data);document.getElementById("content").innerHTML+="</br>"+msg.data;}constpostMessage=(msg)=>{console.log("内嵌页面 postMessage:",msg);broadcast.postMessage(msg);}functionrefreshTime(){var date=newDate();postMessage(date.getHours()+":"+date.getMinutes()+":"+date.getSeconds());}2.window.postMessage
可以跨域,比如有两个页面:
父页面:http://localhost:8080/message1.html
<html><head><meta charset="utf-8"><title>跨域父页面</title><meta http-equiv='expires'content='0'/><meta http-equiv='Cache-Control'content='no-cache'/></head><body><div style="margin-top:10px;";><button onclick="openWindow();"style="width:100px">打开子页面</button><button onclick="openIframe();"style="width:100px">打开iframe</button>打开子页面或iframe任选一个<br/><input id="say"value=""/><button onclick="send();"style="width:100px">同源发送</button><button onclick="send2();"style="width:100px">异源发送</button><span id="content"></span></div><iframe id="iframe"src=""></iframe><script type="text/javascript">//子页面var openner;//子页面 网址var url="http://localhost:8081";//监听消息window.addEventListener("message",(e)=>{console.log("message1 收到消息:",e);document.getElementById("content").innerHTML+=e.data+"<br/>";})//同源发送constsend=()=>{let msg=document.getElementById("say").value;console.log("message1 发送同源消息:",msg);window.postMessage(msg,location.origin);}//打开子页面constopenWindow=()=>{console.log("打开子页面")openner=window.open(url+"/message2.html","_blank ","window")}//打开子页面constopenIframe=()=>{console.log("打开子页面 iframe");openner=window.frames[0];document.getElementById("iframe").src=url+"/postMessage2.html";}//异源发送constsend2=()=>{if(openner){let msg=document.getElementById("say").value;console.log("openner 发送异源消息:",msg);openner.postMessage(msg,url);}else{console.log("请先打开跨域页面");}}</script></body></html>子页面:http://localhost:8081/message2.html
<html><head><meta charset="utf-8"><title>跨域子页面</title><meta http-equiv='expires'content='0'/><meta http-equiv='Cache-Control'content='no-cache'/></head><body><div style="margin-top:10px;";><input id="say"value=""/><button onclick="send();"style="width:100px">同源发送</button><button onclick="send2();"style="width:100px">异源发送</button><br/><br/><span id="content"></span></div><script type="text/javascript">var url="http://localhost:8080";//监听消息window.addEventListener("message",(e)=>{console.log("message2 收到消息:",e);document.getElementById("content").innerHTML+=e.data+"<br/>";})//同源发送constsend=()=>{let msg=document.getElementById("say").value;console.log("message2 发送同源消息:",msg);window.postMessage(msg,location.origin);}//异源发送constsend2=()=>{let msg=document.getElementById("say").value;console.log("message2 发送异源消息:",msg);//打开者,或者 iframe父类let dad=window.opener||window.parent;//如果url填写 *,则发送的消息,允许任何打开message2的父页面,都可以监听到dad.postMessage(msg,url);}</script></body></html>jsonp
JSONP是一种跨域数据请求的技术,它通过动态创建script标签来实现请求。不安全。
核心方法:
functionhandleJSONP(data){console.log(data);}var script=document.createElement('script');//服务器返回时,会根据callback参数,创建一个名为handleJSONP这个的回调函数script.src='https://example.com/api/data?callback=handleJSONP';document.body.appendChild(script);完美展示
jsonp=(url,params)=>{// 1 根据 url 和params 拼接请求地址url+='?'for(let k in params){url+=k+'='+params[k]+'&'}// 2 拼接 callbackconstcallbackName='itcast'+(newDate()-0)url+='callback='+callbackName// 3 动态创建script标签constscript=document.createElement('script');script.type='text/javascript';returnnewPromise((resolve,reject)=>{// 给window添加一个函数,就相当于全局函数window[callbackName]=function(data){// data 就是 JSONP接口返回的数据console.log("jsonp callback:",data);// 调用resolve获取数据resolve(data)// 删除掉添加给window的属性delete window[callbackName]// 移除 script 标签document.head.removeChild(script)}script.src=url;document.head.appendChild(script);})}jsonp(url,{param:'xx',}).then((res)=>{console.log("res:",res);})