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
            }
		}
	}
}
相关推荐
tanxiaomi1 小时前
通过HTML演示JVM的垃圾回收-新生代与老年代
前端·jvm·html
palpitation971 小时前
Android App Links 配置
前端
FuckPatience1 小时前
Vue 组件定义模板,集合v-for生成界面
前端·javascript·vue.js
sophie旭1 小时前
一道面试题,开始性能优化之旅(3)-- DNS查询+TCP(三)
前端·面试·性能优化
开心不就得了1 小时前
构建工具webpack
前端·webpack·rust
gerrgwg1 小时前
Flutter中实现Hero Page Route效果
前端
不枯石1 小时前
Matlab通过GUI实现点云的ICP配准
linux·前端·图像处理·计算机视觉·matlab
hhzz2 小时前
Pythoner 的Flask项目实践-在web页面实现矢量数据转换工具集功能(附源码)
前端·python·flask
lypzcgf2 小时前
Coze源码分析-资源库-编辑工作流-前端源码-核心流程/API/总结
前端·工作流·coze·coze源码分析·智能体平台·ai应用平台·agent平台
lypzcgf2 小时前
Coze源码分析-资源库-编辑工作流-前端源码-核心组件
前端·工作流·coze·coze源码分析·智能体平台·agent平台