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
            }
		}
	}
}
相关推荐
To_OC4 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic5 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy5 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志5 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble6 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯7 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜8 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司8 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
kaiking_g8 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js
江华森9 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http