前端实现跳转子系统,但限制只能跳转一次

项目要求在主系统页面,点击子系统图标-后端返回子系统url-跳转到第三方子系统新窗口,但限制只能跳转一次。

1.记录子系统窗口window对象

于是一开始的实现方案是把子系统新窗口的window对象记录下来,每次点击图标前判断该window的closed属性,如果为false就是没关闭,就弹出"每个应用只能跳转一次,请到对应窗口进行操作"之类的提示语。

javascript 复制代码
handleClick(clientId) {
  // 先判断是否已打开窗口
  if (window[clientId] && !window[clientId].closed) {
    this.$message({ type: 'warning', message: '每个应用只能跳转一次,请切换到对应窗口进行操作' });
  } else {
    // 调用接口
    inter(clientId).then(res => {
      const childWindow = window.open(res.url);
    });
  }
}

但是发现一旦页面刷新,就能突破只能跳转一次的限制,原因是刷新后存储的window会清空,无法实现持久化储存,而window对象也无法存入localStorage、sessionStorage。

然后思考是否可以后端存储子系统窗口的状态,如果点击+跳转过,就不能再次跳转。

然而这种方案需要监听子窗口关闭事件,关闭后需要通知后端更新子窗口状态。但浏览器没有提供关闭事件,只有beforeunload或者unload这种事件,这俩事件除了关闭、刷新页面也可触发。因此放弃这种方案。

2.把需求改为永远跳转到同一个子窗口

如果限制是"只能跳转一次",那每次都跳转到同一个子窗口,其实也是满足需求的。

于是方案改为:先打开唯一名称但不设置url的子窗口,然后判断该窗口的url是否为"about:blank",如果是的话,说明该名称的窗口没有被打开过,则发起请求,然后把后端返回正确的url赋给子窗口的location.href。如果子窗口的url不是"about:blank",那说明已经打开过,这个动作正好focus到打开过的子窗口上。

大概的代码如下:

javascript 复制代码
handleClick(clientId) {
  // 先尝试打开子窗口,注意子窗口的名称需要唯一
  const childWindow = window.open("", childName + LOGIN_TIME);

  // 如果子窗口的url为about:blank,说明这是第一次打开
  if (childWindow.location.href === "about:blank") {
    // 发送请求,获得正确url
    inter(xxx).then(res => {
      // 也可以childWindow =  window.open(res.url, childName + LOGIN_TIME);
      // 如果子系统和门户系统不同源的话,用上面的方法
      childWindow.location.href = res.url;
    }).catch(err => {
      childWindow.close();
    });
}
}

这种方案遇到的新问题是需要将主窗口的一些数据传递给子窗口,比如子系统的token数据。

一开始使用BroadcastChannel来实现消息传递,但是实际操作发现总是未等子窗口准备好,主窗口就已经传递完毕了,所以pass。 最后使用的是localStorage这种笨方法。

相关推荐
憧憬成为web高手5 小时前
ACTF 12307复现
前端·bootstrap·html
wordbaby6 小时前
Axios 上传大文件崩溃:鸿蒙 RNOH 下 XHR 返回空响应头引发的"假失败"
前端·react native
wordbaby6 小时前
React Native 列表分页实战:下拉刷新与上拉加载的工程化方案
前端·react native
wordbaby6 小时前
脱离 Tab 栏的艺术:React Native 全屏子页面的导航架构实践
前端·react native·harmonyos
陈随易7 小时前
Redis 8.8发布,一定要更新
前端·后端·程序员
wordbaby7 小时前
React Native 新架构落地鸿蒙:跨三端政务级应用的工程实践与深度复盘
前端·react native·harmonyos
晓说前端7 小时前
第一篇:为什么学TypeScript?—— 优势、场景与环境搭建
javascript·ubuntu·typescript
excel8 小时前
为什么我推荐使用 Termius:现代 SSH 工具的完整体验
前端·后端
ZC跨境爬虫8 小时前
模块化烹饪小程序开发日记 Day7:(菜谱详情接口开发与JSON数据读取全流程)
前端·javascript·css·ui·微信小程序·json
এ慕ོ冬℘゜9 小时前
JS 前端基础面试题
开发语言·前端·javascript