uni-app web-view组件使用通信时 使用uni.postMessage小程序接收不到消息

uni-app web-view组件使用通信时 使用uni.postMessage小程序接收不到消息

示例代码:

<template>  
    <view class="">  
        <view class="" v-if="message!=''">{{message}}</view>  
        <web-view v-else ref="myWebview" :src="graphVisUrl" @load="webLoad" @message="getMessage" @onPostMessage="getMessage"></web-view>  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
                courseId:'',  
                graphVisUrl:'',  
                message:''  
            }  
        },  
        onLoad(option) {  
            this.courseId=option.courseId  
            this.graphVisUrl=`https://zxzcs.intelveh.com/graphvis/index.html?courseId=${this.courseId}`  
            console.log(this.graphVisUrl,'this.graphVisUrl');  
        },  
        methods: {  
            webLoad(){  
                // console.log(this.$refs.myWebview,"this.$refs.myWebview");  
                // setTimeout(()=>{  
                    // this.$refs.myWebview.evalJS(`window.handleData(${JSON.stringify(this.graphVisUrl)});`);  
                // },500)  
            },  
            getMessage(e){  
                console.log(e,'getMessage');  
                this.message=JSON.stringify(e)  
            }  
        }  
    }  
</script>  

操作步骤:

引用代码

预期结果:

可以在小程序 @message="getMessage" @onPostMessage="getMessage" 获取到H5中的消息

实际结果:

H5不报错,但是小程序页接收不到消息

bug描述:

H5代码

<!DOCTYPE html>  
<html>  
    <head>  
        <meta charset="utf-8" name="viewport">  
        <title>GraphVis</title>  
        <script src="js/log.js"></script>  
        <script src="js/graphvis.min.js"></script>  
        <script src="js/data.js"></script>  
        <script type="text/javascript" src="js/uniWebview.js"></script> 这里是官方https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js复制到本地了  

        <style type="text/css">  
            .page {  
                width: 100%;  
                height: 100vh;  
                display: flex;  
                align-items: center;  
                justify-content: center;  
                padding: 0;  
                margin: 0;  
                background-color: hsla(216, 100%, 96%, 1);  
                background-image: radial-gradient(at 13% 5%, hsla(214, 100%, 37%, 0.29) 0px, transparent 50%), radial-gradient(at 100% 100%, hsla(254, 66%, 56%, 0.11) 0px, transparent 50%), radial-gradient(at 0% 100%, hsla(355, 100%, 93%, 0) 0px, transparent 50%), radial-gradient(at 61% 52%, hsla(227, 64%, 46%, 0.05) 0px, transparent 50%), radial-gradient(at 88% 12%, hsla(227, 70%, 49%, 0.1) 0px, transparent 50%), radial-gradient(at 100% 37%, hsla(254, 68%, 56%, 0) 0px, transparent 50%);  
            }  

        </style>  
    </head>  
    <body class="page">  
        <div class="left-nav">  
            <div id="dataTransmit">向小程序传递消息</div>  

        </div>  
    </body>  
    <script type="text/javascript">  
        const textContainer = document.getElementById("dataContainer");  
        textContainer.textContent = `小程序消息`;  
        function getUrlParams() {  
            const params = {};  
            const search = window.location.search.slice(1); // 去除问号 "?"  
            if (search) {  
                search.split('&amp;').forEach(item => {  
                    const [key, value] = item.split('=');  
                    params[key] = decodeURIComponent(value); // 解码特殊字符  
                });  
            }  
            return params;  
        }  

        // 2. 调用接口获取数据  
        async function fetchData(params) {  
            try {  
                // 示例接口地址,需替换为实际接口  
                const response = await fetch(`/api/data?${new URLSearchParams(params)}`);  
                if (!response.ok) {  
                    throw new Error('接口请求失败');  
                }  
                const data = await response.json();  
                // 存储数据供后续渲染使用(如存入全局变量或状态管理)  
                window.pageData = data;  
                console.log('数据获取成功:', data);  
            } catch (error) {  
                console.error('数据获取失败:', error);  
            }  
        }  

        // 3. 页面加载前执行(在 head 中同步执行)  
        const urlParams = getUrlParams();  
        // 确保参数存在再请求(例如必须有 id 参数)  
        // if (urlParams.id) {  
        textContainer.textContent = urlParams.courseId  
        console.log(urlParams, 'urlParams');  
        document.addEventListener('UniAppJSBridgeReady', function() {  
          // uni-app js 加载完成  
          uni.postMessage({  
              data:{  
                  event:"ready",  
                  params:null  
              }  
          })  
        });  
    </script>  
</html>
信息类型 信息
产品分类 uniapp/小程序/微信
PC开发环境 Windows
PC开发环境版本号 Windows 11 专业版 24H2
HBuilderX类型 正式
HBuilderX版本号 4.66
第三方开发者工具 1.06.2504030
基础库版本号 3.10.0
项目创建方式 HBuilderX

更多关于uni-app web-view组件使用通信时 使用uni.postMessage小程序接收不到消息的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

更多关于uni-app web-view组件使用通信时 使用uni.postMessage小程序接收不到消息的实战教程也可以访问 https://www.itying.com/category-93-b0.html


在你的代码中,存在几个关键问题导致小程序无法接收到H5发送的消息:

  1. 事件监听器错误:H5代码中使用了document.addEventListener('UniAppJSBridgeReady', ...),但正确的应该是监听UniAppJSBridgeReady事件后,通过uni对象发送消息。不过更推荐直接使用uni.postMessage,因为uni-app环境会自动处理bridge就绪状态。

  2. H5消息发送时机问题UniAppJSBridgeReady事件在小程序端web-view组件加载完成后才会触发,但你的H5代码可能在bridge就绪前就执行了postMessage。

  3. 小程序端事件监听重复:同时监听了[@message](/user/message)@onPostMessage,实际上只需要[@message](/user/message)即可。

解决方案

H5端修改

// 简化消息发送,无需等待JSBridgeReady
setTimeout(() => {
    uni.postMessage({
        data: {
            event: "ready",
            params: null
        }
    });
}, 100);

// 或者通过按钮触发测试
document.getElementById("dataTransmit").addEventListener("click", function() {
    uni.postMessage({
        data: "测试消息"
    });
});

小程序端简化

<web-view :src="graphVisUrl" [@message](/user/message)="getMessage"></web-view>
回到顶部