文章目录
1 前言
- 正常来说想实现持续化存储,都是把值存储在
localStorage
或者sessionStorage
里,此时假设A项目存了个值,此时打开B项目就访问不到A项目存储的值,因为这个值的源是属于A项目的,由于同源策略,B项目肯定是访问不到的
2 场景描述
2.1 场景一:B项目想获得A项目的值,做一些操作
2.2 场景二:A项目跟B项目是在同一个屏幕上(左右屏幕那种),A进行操作后B项目发生改变
2.3 场景三:在以上场景下,不希望页面刷新 / 切换界面后才发生变化
3 解决思路
- 如果想同时满足这三个场景的话,首先,通过接口实现不太现实,如果我先启动B项目,再启动A项目,就算A项目启动后就把值传给了接口,那B项目在不刷新的情况/切换页面情况下是拿不到这个值的,可别打算用定时器每隔多少毫秒去调用接口。
- 通过网址传值也不现实,因为明确说了,A进行操作后B项目发生改变,总不能A操作后就打开一个B项目的新窗口吧
- 此时换一种想法,为何不考虑先把这两个项目展示在一起呢,比如
iframe
4 使用iframe
进行传参
4.1 方法描述
- 此时会使用到
iframe
传参跟刷新界面两种方法
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
- 它有以下配置项:
Window.open
Window.opener
HTMLIFrameElement.contentWindow(父窗体向子窗体发送消息)
Window.parent(子窗体向父窗体发送消息)
Window.frames +索引值
message
将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。
targetOrigin
通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是 *
字符串(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的origin属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
transfer
可选是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
4.2 进行iframe
的传参与接参
// 传参
var obj = {method: "iframeClose"};
window.parent.postMessage(obj, "*", )
// 接参
window.addEventListener('message', function (e) {
if (e.data.method) {
console.log(e);
}
}, false);
4.3 示例代码 - 根据需求在合适的地方使用,写到main.js
文件都行
注意:传参变化后,接参事件会被触发,动态获取传递过来的新参数,不需要关系A项目何时启动,当有参数传递 / 传递参数发生变化都会触发接收参数事件,只需在接收参数事件里额外调用想做出的改变即可。
4.3.1 传参
- 假设这是A项目,启动地址为 http://localhost:8087/#/
<template>
<div class="center"></div>
</template>
<script>
export default {
name: '',
props: {},
components: {},
data () {
return {}
},
computed: {},
watch: {},
created () { },
mounted () {
// 传参
var obj = { method: "我是iframe传递的参数" };
window.parent.postMessage(obj, "*",);
},
methods: {},
}
</script>
<style scoped lang="less">
</style>
4.3.2 接参
- 假设这是B项目,启动地址为 http://localhost:8081/#/
<template>
<div class="">
<!-- A 项目地址 -->
<iframe class="iframe-class" src="http://localhost:8087/#/" frameborder="0"></iframe>
</div>
</template>
<script>
export default {
name: '',
props: {},
components: {},
data () {
return {}
},
computed: {},
watch: {},
created () { },
mounted () {
// 接参
window.addEventListener('message', function (e) {
if (e.data.method) {
console.log(e);
}
}, false);
},
methods: {},
}
</script>
<style scoped lang="less">
.iframe-class{
display: none;
}
</style>