美文网首页
给嵌套的iframe子页[postMessage]传数据

给嵌套的iframe子页[postMessage]传数据

作者: 漫漫江雪 | 来源:发表于2019-01-25 12:39 被阅读0次

场景一: vue组件页嵌套一个普通的html页面

背景:vue组件下嵌套了一个不同域下的子页面,用户的登录信息是保存在vuex中的,iframe子页面,不能直接获取的到(即便把数据存localStorage,子页也一样获取不到),所以只好借用postMessage传数据
主要代码:

<template>
    <div class="home">
        <iframe src="http://127.0.0.1:8888/index.html" class="mapFrame" ref="mapFrame"></iframe>
    </div>
</template>

<script>
    export default {
        mounted() {
            let mapFrame = this.$refs['mapFrame']
            if (mapFrame.attachEvent){  //兼容浏览器判断
                mapFrame.attachEvent("onload", function(){ 
                    let iframeWin = mapFrame.contentWindow
                    iframeWin.postMessage({
                        method: 'getBaseInfo',
                        data:'我是vuex state的数据'
                    },'*')
                })
            } else { 
                mapFrame.onload = function(){ 
                    let iframeWin = mapFrame.contentWindow
                    iframeWin.postMessage({
                        method: 'getBaseInfo',
                        data:'我是vuex state的数据'
                    },'*')
                } 
            }
            
        }
    }
</script>

<style scoped lang="stylus">
.home {
    .mapFrame {
        height: 300px;
        width: 500px;
    }
}
</style>

子页面 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>iframe嵌套网页测试</title>
</head>
<body>
    子页面
    <script>
        window.addEventListener('message',function(e){
            console.log('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
            console.log(e.origin,e.data)
        })  
        // window.postMessage({
        //     method:'localtest',
        //     data:'ddddddddddddddddddddddddddddd'
        // },'*')
    </script>
</body>
</html>

场景二: 一个普通的页面嵌套 vue页面,通过事件给iframe vue页发消息

  • 普通页
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>通过postMessage给iframe页面发消息</title>
    <style>
        *{margin: 0; padding: 0;}
        .mapFrame {
            width: 1000px;
            height: 500px;
        }
    </style>
</head>
<body>
    <div id="app">
        <button @click="changeArea">改变区域</button>
        <iframe src="http://localhost:8081/#/mainmap" class="mapFrame" ref="mapFrame"></iframe>
    </div>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
    <script>        
        var app=new Vue({
            el:'#app',
            mounted() {
                /*页面一加载完成就发消息的情景*/
                let mapFrame = this.$refs['mapFrame']
                if (mapFrame.attachEvent){  //兼容浏览器判断
                    mapFrame.attachEvent("onload", function(){ 
                        let iframeWin = mapFrame.contentWindow
                        iframeWin.postMessage({
                            method: 'getBaseInfo',
                            data:'我是vuex state的数据'
                        },'*')
                    })
                } else { 
                    mapFrame.onload = function(){ 
                        let iframeWin = mapFrame.contentWindow
                        iframeWin.postMessage({
                            method: 'getBaseInfo',
                            data:'我是vuex state的数据'
                        },'*')
                    } 
                }               
            },
            methods:{
                changeArea() {  // 更改区域, 类似的页面更改主题也可以用这种方式去通知
                    this.$refs.mapFrame.contentWindow.postMessage({
                        method: 'changeArea',
                        data: {
                            province_code: '520000',
                            city_code: '520200'
                        }
                    },'*')
                }
            }
        })
    </script>
</body>
</html>
  • iframe vue页接收消息
  1. 先在main.js中监听message消息
var Bus = new Vue()   // 事件总线,方便后期全局调用  参考:http://www.cnblogs.com/fanlinqiang/p/7756566.html

new Vue({
  router,
  data: {
    Bus
  },
  render: h => h(App)
}).$mount('#app')

window.addEventListener('message',function(e){
  console.log('收到更改区域的消息',e.data)
  if(e.data && e.data.method == 'changeArea') {  // 如果收到的消息是更改区域, 触发changearea事件, 监听该事件的组件页面作相应的处理
    var dataObj = e.data.data
    Bus.$emit('changearea',dataObj.province_code, dataObj.city_code)
  }
})
  1. mainmap.vue组件 监听事件总线Bus的 changearea事件
mounted() {
    //this.init()
    //this.initMQTT() //初始化mqtt
    //this.addareaborder()
    this.$root.Bus.$on('changearea',this.handleChangeArea)  // 监听根实例下的Bus事件
},
methods: {
        ...
    handleChangeArea(pcode,ccode) {            
        changeArea(pcode,ccode)  // 更新配置文件中的省和市区域编码
        this.addareaborder()
    },
        ...
},
beforeDestroy() {
    this.client.end()
    this.client = null
    this.$root.Bus.$off('changearea',this.handleChangeArea)  // 组件销毁时卸载事件监听
}
iframe-postMessage.gif

相关文章

网友评论

      本文标题:给嵌套的iframe子页[postMessage]传数据

      本文链接:https://www.haomeiwen.com/subject/jpsmjqtx.html