如何实现浏览器标签页之间的通信

浏览器标签页之间通信的实现

使用场景

​ 前端开发过程中,总是避免不了要进行前端标签页之间的通信,最经典的例子莫过于音乐播放网站中,当第一次点击播放列表中的歌曲时,它会打开一个新的标签页进行播放,而当在列表中再次点击歌曲播放时,并不会再多打开一个标签页,而是会在刚才新打开的标签页上播放歌曲。

方式方法

这里跳转新页面均使用window.open[[1]](#[1])方法,这里稍微说下window.open方法的参数

  • url(可选)

    一个字符串,表示要加载的资源的 URL 或路径。如果指定空字符串("")或省略此参数,则会在目标浏览上下文中打开一个空白页。

  • target(可选)

    一个不含空格的字符串,用于指定加载资源的浏览上下文的名称。如果该名称无法识别现有的上下文,则会创建一个新的上下文,并赋予指定的名称。还可以使用特殊的 target 关键字:_self_blank_parent_top

    该名称可用作<a><form>元素的target属性。

  • windowFeatures(可选)

    一个字符串,包含以逗号分隔的窗口特性列表,形式为 name=value,布尔特性则仅为 name。这些特性包括窗口的默认大小和位置、是否打开最小弹出窗口等选项。

    在下面的例子中采用audio,作为浏览上下文的名称,让他从始至终只创建一个新的标签页

1.使用路由上的query传参

list.html

javascript 复制代码
const broadCastChannel = new BroadcastChannel('audio')
function showAudio(){
    //方式一:通过query,缺点会刷新已打开的页面,但并没有同源策略影响
    window.open('/audio.html?name=张三&id=555','audio')
}

audio.html

javascript 复制代码
const app = document.getElementById('app')
const query = new URLSearchParams(window.location.href.split('?')[1])
app.innerText = query.get('name')

优点:每次打开,audio页面都会变为当前活动标签页

缺点:

  • 每次打开,audio页面都会被刷新,重新加载
  • 如果新打开的浏览上下文不共享相同的源[[2]](#[2]),则打开脚本将无法与浏览上下文的内容进行交互(读取或写入)。

2.使用localStroage监听

利用同源页面[[2:1]](#[2:1])共享localStroage的特性,利用windw.addEventLister监听stroage[[3]](#[3])的变化,来实现两个标签页的通信,详细查看下面例子:

list.html

javascript 复制代码
function showAudio(){
    if(!localStorage.getItem('hasAudio')){
        window.open('/audio.html','audio')
        localStorage.setItem('hasAudio',1)
    }
    setTimeout(()=>{
        localStorage.setItem('name','李四')
    },3000)
}

audio.html

javascript 复制代码
window.onunload = () =>{
    localStorage.removeItem('hasAudio')
    localStorage.removeItem('name')
}
const app = document.getElementById('app')
window.addEventListener('stroage',e=>{
	const app = document.getElementById('app')
    app.innerText = e.newValue
})

优点:

  • 第一次打开,之后再传参无需刷新界面重新加载资源

缺点:

  • 打开页面的需为同源页面,localStroage在同源页面中共享
  • 同源页面需通过localStroage检控通信,控制麻烦,复杂场景使用不方便

3.使用BroadcastChannel

BroadcastChannel 接口代理了一个命名频道,可以让指定 origin 下的任意 browsing context 来订阅它。它允许同源[[2:2]](#[2:2])的不同浏览器窗口,Tab 页,frame 或者 iframe 下的不同文档之间相互通信。通过触发一个 message 事件,消息可以广播到所有监听了该频道的 BroadcastChannel 对象。

list.html

javascript 复制代码
const broadCastChannel = new BroadcastChannel('audio')
function showAudio(){

    if(!localStorage.getItem('hasAudio')){
        window.open('/audio.html','audio')
        localStorage.setItem('hasAudio',1)
    }

    setTimeout(()=>{
        broadCastChannel.postMessage({name:'李四'})
    },3000)

}

audio.html

javascript 复制代码
window.onunload = () =>{
    localStorage.removeItem('hasAudio')
}
const app = document.getElementById('app')
const broadCastChannel = new BroadcastChannel('audio')
broadCastChannel.addEventListener('message',e=>{
    const {name} = e.data
	const app = document.getElementById('app')
    app.innerText = name
})

优点:

  • 第一次打开,之后再传参无需刷新界面重新加载资源
  • 需要共用频道的页面,通信简单

缺点:

  • 打开页面的需为同源页面[[2:3]](#[2:3])BroadcastChannel只会向命名频道相同的同源页面发送和接收消息

  1. window.open文档 ↩︎

  2. 同源页面:即http协议相同且端口号和ip地址相同的网页 ↩︎ ↩︎ ↩︎ ↩︎

  3. stroage事件文档 ↩︎

相关推荐
界面开发小八哥26 分钟前
界面控件DevExpress Blazor v26.1新版亮点 - TreeList & 数据编辑器
javascript·编辑器·.net·界面控件·blazor·devexpress·用户界面
风月说与山鬼34 分钟前
二、uni-app入口文件(main.js)
javascript·uni-app
mCell9 小时前
Lua 编程入门:从基础语法到元表
javascript·算法·lua
伟大的兔神10 小时前
我做了一个本地优先的 AI 图片工作台:Loomora v1.0.0 正式发布
前端·javascript·vue.js
fangzhanpeng16812 小时前
(前端)2.js变量作用域样例
开发语言·前端·javascript
码艺-Alimjan14 小时前
Vue项目源码备份最佳实践:无视node_modules,打包体积仅2MB
前端·javascript·vue.js
xixiaoyunya16 小时前
JavaScript 异步编程全解析:从回调地狱到 async/await 的演进之路
开发语言·javascript·ecmascript
张元清16 小时前
React useScrollLock Hook:为弹窗锁住页面滚动 (2026)
javascript·react.js
Sayai16 小时前
【无标题】ECharts 实现日志量异常检测:基线 ±Kσ 基带 + 灵敏度切换(Vue2 实战)
前端·javascript·echarts
默_笙17 小时前
💌 为了把"主题色"传给孙子组件,我翻了五层楼——直到遇见了 useContext
前端·javascript