关于javascript:Tab页面互相通信

45次阅读

共计 1727 个字符,预计需要花费 5 分钟才能阅读完成。

原文地址
这是一篇拖更了一个月的文章,200727 才想起来把它写了,让咱们坐上工夫穿梭机回到一个月前。


最近写后盾的前端遇到奇葩的需要,单体利用要做出多开多个 Tab。而且有些数据不能从独自的接口获取,它会在第一次接口申请全副返回。因为数据量太大,如果关上新 Tab 的时候再申请一次体验不大好,也存在节约申请的状况。因而一个技术需要就呈现了,须要一个在多不同 Tab 之间互相通信的机制。

第一版的实现是间接用的 localStorage,给本人挖了一个坑(真蔡)。因为刷新页面的时候还要能从新读取数据,所以不能利用 localStorage 写入、读取之后就立马革除掉。上线之后没过多久失去反馈页面关上之后空白,因为我这边关上失常,一开始没太在意。不久之后又失去同样的反馈,看来还是得排除一下问题了。间接去反馈者查看一下异样信息,看来是 localStorage 超过了空间限度。先给了他们革除 localStorage 的长期解决方案。

因为第一版的实现没有做革除,我须要的最现实成果是在 Tab 敞开之后能间接实现革除数据,所以我想到了用 sessionStorage 来解决问题,人造的和 Tab 相关联,Tab 敞开就革除了,完满!接下来须要解决的一个问题就是怎么把数据从一个 Tab 传到新开的 Tab?思考不到几分钟我就想到了计划,答案就是利用 window.opener 属性。我之前怎么就没想到!(╯□╰)

实现

个别咱们关上一个外链的时候,会这样写:

<a href="https://cn.bing.com" target="_blank" rel="noopener noreferrer"> 必应 </a>

这样能够防止关上的外链页面能够通过 window.opener 来非法拜访咱们本人的页面。而咱们当初就是要去掉rel="noopener noreferrer",利用这个个性来实现需求。

function getSessionItem(key, remove) {if (!key) {
    // thisLocation is defined as a const at the top of the file, just ignore.
    throw new Error(`[${thisLocation}] - invalid key: ${key}`);
  }
  if (remove === undefined) {remove = true;}
  let o = window.sessionStorage.getItem(key);
  if (!o && window.opener) {o = window.opener.sessionStorage.getItem(key);
  }

  if (window.opener && remove) {window.opener.sessionStorage.removeItem(key);
  }

  return o || undefined;
}

function setSessionItem(key, value) {if (!key) {throw new Error(`[${thisLocation}] - invalid key: ${key}`);
  }
  window.sessionStorage.setItem(key, value);
}

getSessionItem 这个函数会先尝试在本人的 sessionStorage 里获取数据,如果数据不存在则从 opener 的 sessionStorage 获取,接下来就是革除 sessionStorage 里的数据,最初返回。获取到数据之后,再调用 setSessionItem 办法,这样页面从新刷新也能失去数据,能够一直刷新。当用户敞开这个 Tab 之后,数据就主动被浏览器销毁了,达到了咱们想要的成果。

总结

能够看到,写代码的时候,如果没有留神设置 rel="noopener noreferrer" 是很容易呈现平安问题的。而如果是关上咱们本人的页面到能够不必设置,反过来还能够实现相似下面的成果。还有什么?我甚至能够注册一个闭包函数到 window 对象上,当关上新标签之后,新开的 Tab 在须要的时候就能够调用回调函数,告诉原来的 Tab 去解决一些逻辑,同时传输一些数据,甚至能够本人也注册回调函数,把本人的 window 对象传过来,就能够实现不同 Tab 间接双向通信了!

正文完
 0