浏览器跨页面通信,现在大概有2种方法:
同源访问,更加安全,必须放在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>
const broadcast = new BroadcastChannel('Broadcast');
//订阅消息
broadcast.onmessage = (msg) => {
console.log("主页面 onmessage:",msg.data);
document.getElementById("time").innerHTML= msg.data;
}
const postMessage = (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>
const broadcast = new BroadcastChannel('Broadcast');
//订阅消息
broadcast.onmessage = (msg) => {
console.log("内嵌页面 onmessage:",msg.data);
document.getElementById("content").innerHTML+= ""+msg.data;
}
const postMessage = (msg)=>{
console.log("内嵌页面 postMessage:",msg);
broadcast.postMessage(msg);
}
function refreshTime(){
var date=new Date();
postMessage(date.getHours()+":"+date.getMinutes()+":"+date.getSeconds());
}
可以跨域,比如有两个页面:
父页面: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+"
";
})
//同源发送
const send = ()=>{
let msg = document.getElementById("say").value;
console.log("message1 发送同源消息:",msg);
window.postMessage(msg,location.origin);
}
//打开子页面
const openWindow=()=>{
console.log("打开子页面")
openner = window.open(url+"/message2.html", "_blank ","window")
}
//打开子页面
const openIframe=()=>{
console.log("打开子页面 iframe");
openner = window.frames[0];
document.getElementById("iframe").src = url+"/postMessage2.html";
}
//异源发送
const send2 = ()=>{
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+"
";
})
//同源发送
const send = ()=>{
let msg = document.getElementById("say").value;
console.log("message2 发送同源消息:",msg);
window.postMessage(msg,location.origin);
}
//异源发送
const send2 = ()=>{
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是一种跨域数据请求的技术,它通过动态创建script标签来实现请求。不安全。
核心方法:
function handleJSONP(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 拼接 callback
const callbackName = 'itcast' + (new Date() - 0)
url += 'callback='+ callbackName
// 3 动态创建script标签
const script = document.createElement('script');
script.type = 'text/javascript';
return new Promise((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);
})