uni-app x开发跨端应用,与web-view的双向通信解决方案

实现方案

1. 消息格式设计:

  • 网页向 APP 发送的消息格式:采用 JSON 结构,包含 type (消息类型)、 data ( payload 数据)和 callbackId (唯一标识每个请求的回调函数)
  • 消息格式示例:
go 复制代码
{
    type: 'GET_USER_INFO', // 消息类型
    data: { id: '123456' }, // 消息内容
    callbackId: 'cb_1698850392834_0.3255338999917584' // 回调标识   
}

2. 回调函数管理:

  • 网页端使用全局对象 window.__webview_callbacks 存储回调函数
  • 通过 callbackId 实现请求-响应的精准匹配
  • 内置 60 秒超时清理机制,防止内存泄漏

3.消息传递机制:

  • H5 → App:网页通过 uni.webView.postMessage() 发送消息到 App
  • App 通过 @message 事件监听来自网页的消息
  • App → H5:通过 evalJS() 执行 H5 端的 handleAppCallback() 函数

3. 跨平台兼容:

  • 实际应用中应添加平台判断逻辑,实现跨平台兼容

具体实现

H5端核心代码

引入uni.webview.1.5.5.js文件,调用uni.webview.postMessage()方法,向web-view发送消息。

xml 复制代码
<script type="text/javascript" src="uni.webview.1.5.5.js"></script>
xml 复制代码
<script type="text/javascript">
	// 消息回调映射表(用于处理异步回调)
	const callbackMap = new Map()
	// 发送消息到 APP
	function postToApp(messageType, payload, callback) {
		const callbackId = `cb_${Date.now()}_${Math.random().toString(36).substr(2)}`
		// 注册回调
		if (typeof callback === 'function') {
			callbackMap.set(callbackId, callback)
			// 将回调函数存储到全局对象中
			window.__webview_callbacks = window.__webview_callbacks || {};
			window.__webview_callbacks[callbackId] = callback;
		}
		// 发送消息
		uni.webView.postMessage({
			data: {
				type: messageType,
				data: payload,
				callbackId: callbackId
			}
		})
	}
	// 处理来自App的回调
	function handleAppCallback(callbackId, result) {
		if (window.__webview_callbacks && window.__webview_callbacks[callbackId]) {
			window.__webview_callbacks[callbackId](result);
			// 执行完回调后删除该回调函数
			delete window.__webview_callbacks[callbackId];
		}
	}
    // 添加超时清理机制,避免内存泄漏
    setInterval(() => {
        callbackMap.forEach((callback, callbackId) => {
            if (callbackMap.has(callbackId)) {
                callbackMap.delete(callbackId)
                delete window.__webview_callbacks[callbackId];
                console.warn(`Callback ${callbackId} timeout`)
            }
        })
    }, 60_000) // 60秒检查一次
    // 调用示例,获取用户信息
    function getUserInfo() {
        postToApp('GET_USER_INFO', {
            id: '233333'
        }, (response) => {
            if (response.status === 'success') {
                console.log('User Info:', response.data)
            } else {
                console.error('Error:', response.message)
            }
        })
    }
</script>

uni-app x端核心代码

在web-view组件上监听@message事件,处理来自H5的消息。

xml 复制代码
<template>
	<view class="container">
		<web-view :src="webViewUrl" :onMessage="handleMessage" />
	</view>
</template>

<script>
export default {
	data() {
		return {
            webViewUrl: 'https://...'
		}
	},
	methods: {
		handleMessage(event) {
			console.log('接收到的消息:', event.data); // 打印接收到的消息
			// 在这里处理接收到的消息
            let data = event.detail.data[0]		
            if( data.type == 'GET_USER_INFO'){
                console.log("-----------GET_USER_INFO-------")
                let callbackId = data.callbackId
                const webview = uni.getElementById('web-view') as UniWebViewElement
                let result = {
                    status: 'success',
                    data: {
                        name: '张三'
                    }
                }
                let res = JSON.stringify(result)
                const callbackScript = `handleAppCallback('${callbackId}', ${res});`;
                webview.evalJS(callbackScript)
                return
            }
		}
	}
}
相关推荐
麦麦大数据14 分钟前
F051-vue+flask企业债务舆情风险预测分析系统
前端·vue.js·人工智能·flask·知识图谱·企业信息·债务分析
1024肥宅17 分钟前
现代 JavaScript 特性:ES6+ 新特性深度解析与实践
前端·javascript·面试
速易达网络25 分钟前
基于Java Servlet的用户登录系统设计与实现
java·前端·mvc
晨光321143 分钟前
Day34 模块与包的导入
java·前端·python
BD_Marathon1 小时前
Vue3_关于CSS样式的导入方式
前端·css
苹果电脑的鑫鑫1 小时前
vue和react缩进规则的配置项如何配置
前端·vue.js·react.js
BD_Marathon1 小时前
Vue3_工程文件之间的关系
前端·javascript·vue.js
weibkreuz1 小时前
模块与组件、模块化与组件化的理解@3
开发语言·前端·javascript
拾忆,想起1 小时前
单例模式深度解析:如何确保一个类只有一个实例
前端·javascript·python·微服务·单例模式·性能优化·dubbo
RealizeInnerSelf丶1 小时前
Web 网页如何唤起本地 Windows 应用并传递参数(含 Electron 自动注册 + 手动配置指南)
前端·windows