简单,粗暴,高效。js实现一个浏览器多标签同步更新登录状态

71 阅读1分钟

项目技术栈为nuxt3+vue3 大概功能实现主要是点击登录按钮成功登录后同一个浏览器下其他标签同步登录状态 实现原理

  1. BroadcastChannel API:现代浏览器提供的跨标签页通信机制

  2. 频道匹配:两个页面使用相同频道名称('auth_channel')建立连接

  3. 状态同步

    • 标签页1登录后通过postMessage发送状态
    • 标签页2通过监听onmessage事件接收状态

注意事项:

  1. 需要现代浏览器支持(Chrome 47+,Firefox 44+,Edge 16+)
  2. 同源策略限制(需相同协议+域名+端口)
  3. 实际项目中需结合真实登录逻辑和状态管理

具体代码如下创建广播频道部分

      showToast({
        title: "登录成功",
      });
      const { setToken, getMe, setAuthBasic } = useUserStore();
      const { $bus } = useNuxtApp();
      setToken({
        accessToken: loginRes.data.accessToken,
        refreshToken: loginRes.data.refreshToken.tokenValue,
      });
      setAuthBasic(loginRes.data);
      $bus.emit(AppEvent.LoginDialog, false);
      await getMe();
      // 创建广播频道
      const channel = new BroadcastChannel('auth_channel');
      const loginStatus = {
        isLoggedIn: true, token: {
          accessToken: loginRes.data.accessToken,
          refreshToken: loginRes.data.refreshToken.tokenValue,
        }
      };
      // 发送登录状态到其他标签页
      channel.postMessage(loginStatus);
    }

信息接收页面代码如下展示,这里我引用了getMe()方法是本项目里的刷新用户信息token所用,可根据自己的项目做处理

const channel = new BroadcastChannel("auth_channel");
const { setToken, getMe, setAuthBasic } = useUserStore();
// 监听登录状态
channel.onmessage = (event) => {
  console.log(event, "event");
  if (event.data.isLoggedIn) {
    setToken(event.data.token);
    getMe();
  } else {
  }
};