不同源浏览器页面实现通信

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>
  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
同源策略是一种浏览器安全机制,用于限制一个(域名、协议和端口)的文档或脚本如何与另一个的资进行交互。同源策略的目的是防止恶意网站通过脚本访问用户的敏感信息或执行恶意操作。 在同源策略下,一个的文档或脚本只能与同一的资进行交互,不能直接访问其他的资。这意味着,如果一个页面中包含一个来自不同iframe元素,那么该iframe中的文档或脚本将无法直接访问父页面的DOM,也无法通过常规的方式与父页面进行通信。 然而,同源策略并不是绝对的,有一些方法可以绕过同源策略实现跨域访问,其中包括以下几种常见的方法: 1. JSONP跨域:通过动态创建`<script>`标签,将跨域请求的数据作为回调函数的参数返回到页面中。 2. document.domain + iframe跨域:当两个页面的域名相同但是子域不同,可以通过设置`document.domain`属性来实现跨域访问。 3. location.hash + iframe跨域:通过改变iframe的URL的hash值来传递数据,从而实现跨域通信。 4. window.name + iframe跨域:通过在iframe的`window.name`属性中存储数据,实现跨域通信。 5. postMessage跨域:通过使用`window.postMessage()`方法在不同窗口之间传递消息,实现跨域通信。 6. 跨域资共享(CORS):在服务器端设置响应头,允许指定的进行跨域访问。 7. nginx代理跨域:通过配置nginx服务器代理请求,实现跨域访问。 8. nodejs中间件代理跨域:通过使用nodejs中间件代理请求,实现跨域访问。 9. WebSocket协议跨域:通过WebSocket协议进行跨域通信。 总结起来,同源策略是浏览器的一种安全机制,限制了不同之间的交互。但是通过一些特定的方法,可以实现跨域访问和通信

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值