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
            }
		}
	}
}
相关推荐
Kiri霧9 分钟前
Kotlin抽象类
android·前端·javascript·kotlin
ai小鬼头42 分钟前
创业小公司如何低预算打造网站?熊哥的实用建站指南
前端·后端
阿星做前端1 小时前
聊聊前端请求拦截那些事
前端·javascript·面试
阿凤211 小时前
在UniApp中防止页面上下拖动的方法
前端·uni-app
拾光拾趣录1 小时前
DocumentFragment:高性能DOM操作
前端·dom
归于尽1 小时前
从JS到TS:我们放弃了自由,却赢得了整个世界
前端·typescript
palpitation972 小时前
Fitten Code使用体验
前端
byteroycai2 小时前
用 Tauri + FFmpeg + Whisper.cpp 从零打造本地字幕生成器
前端
用户1512905452202 小时前
C 语言教程
前端·后端
UestcXiye2 小时前
Rust Web 全栈开发(十):编写服务器端 Web 应用
前端·后端·mysql·rust·actix