玩转 UniApp WebView:H5 与原生应用双向通信实战

玩转 UniApp WebView:H5 与原生应用双向通信实战

在 UniApp 开发中,WebView 是连接原生应用与 H5 页面的重要桥梁,尤其在需要复用已有 Web 页面或集成复杂 Web 交互场景时不可或缺。本文将结合实际开发案例,详细讲解如何实现 UniApp(App/H5 端)与内嵌 H5 页面的双向通信,并封装常用的原生能力调用(扫码、拨打电话、蓝牙打印、文件上传等)。

一、核心需求与技术背景

你需要在 UniApp 中通过 WebView 嵌入 H5 页面,并实现:

  1. H5 页面触发原生能力(扫码、拨打电话、蓝牙打印、图片 / 视频上传);
  2. UniApp 原生端处理完逻辑后,将结果回传给 H5 页面;
  3. 兼容 App 端和 H5 端的通信逻辑;
  4. 给 H5 页面传递鉴权 Token 等参数。

二、整体实现思路

  1. 参数传递:UniApp 在打开 WebView 时,通过 URL 拼接方式给 H5 页面传递 Token 等参数;
  2. H5 → UniApp:H5 通过uni.webView.postMessage发送指令,UniApp 监听message事件接收并处理;
  3. UniApp → H5:UniApp 通过evalJS执行 H5 页面的全局函数,将处理结果回传;
  4. 端兼容:通过 UniApp 的条件编译区分 App 端和 H5 端的通信逻辑。

三、代码实现详解

3.1 UniApp 端:WebView 容器页面

<template><view style="position: relative;"><web-view :src="reportSrc":webview-styles="webviewStyles" @message="message"></web-view></view></template><script>import{ getToken }from'@/utils/auth'import cameraTool from'../mixins/camera-tool.vue'// 上传功能混入var wv;// WebView实例exportdefault{mixins:[cameraTool],data(){return{webviewStyles:{width:'100%',height:'100%'},reportSrc:''};},onLoad(option){// 接收打开页面时传递的参数const eventChannel =this.getOpenerEventChannel(); eventChannel.on('acceptDataFromOpenerPage',(data)=>{this.reportSrc =this.addQueryParam(data.url,`token=${getToken()}`); uni.setNavigationBarTitle({title: data.title });});// #ifdef APP-PLUSthis.initAppWebView();// #endif// #ifdef H5this.initH5Listener();// #endif},methods:{// App端WebView初始化initAppWebView(){ uni.showLoading({title:'加载中'});var currentWebview =this.$scope.$getAppWebview();setTimeout(()=>{ wv = currentWebview.children()[0]; uni.hideLoading();},1000);},// H5端监听initH5Listener(){ window.addEventListener('message',(e)=>{ console.log('接收H5消息', e.data);},false);},// URL拼接TokenaddQueryParam(url, param){return url.includes('?')?`${url}&${param}`:`${url}?${param}`;},// 接收H5发来的消息(核心)message(e){const data = e.detail.data[0];const{ type, info, options }= data;const actions ={'scanCode':()=>this.handleScan(info),'phoneCall':()=>this.handlePhoneCall(info),'bluetoothPrint':()=>this.handleBluetoothPrint(info),'chooseImage':()=>this.handleChooseImage(options),'chooseVideo':()=>this.handleChooseVideo(options),'logout':()=>this.handleLogout()};if(actions[type]){ actions[type]();}else{ console.warn('未知操作类型:', type);}},// 扫一扫handleScan(){ uni.scanCode({success:(res)=>{ wv.evalJS(`window.scanCodeFromUniApp('${res.result}')`);}});},// 拨打电话handlePhoneCall(phoneNumber){ uni.makePhoneCall({phoneNumber: phoneNumber ||'114'});},// 蓝牙打印(跳转蓝牙页面)handleBluetoothPrint(printData){ uni.navigateTo({url:`/pages/common/blueTooth/index?printData=${JSON.stringify(printData)}`});},// 上传图片asynchandleChooseImage(options){try{const imageUrl =awaitthis.uploadImage(options); wv.evalJS(`window.chooseImageFromUniApp(${JSON.stringify(imageUrl)})`);}catch(error){ console.error('图片上传失败', error);}},// 上传视频asynchandleChooseVideo(options){try{const videoUrl =awaitthis.uploadVideo(options); wv.evalJS(`window.chooseVideoFromUniApp(${JSON.stringify(videoUrl)})`);}catch(error){ console.error('视频上传失败', error);}},// App主动向H5传值submit(){const data ={name:'wft',timestamp: Date.now()}; wv.evalJS(`window.msgFromUniApp(${JSON.stringify(data)})`);}}};</script>

3.2 H5 端:页面结构与通信逻辑

3.2.1 HTML 入口文件(index.html)
<!DOCTYPE html><html><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/></head><body><div id="app"></div><!-- 关键:引入 uni.webView 桥接文件 --><script src="./uni.webview.js" type="text/javascript"></script><script type="text/javascript">// 等待桥接就绪 document.addEventListener("UniAppJSBridgeReady",function(){ uni.webView.getEnv(function(res){ console.log("当前环境:", res);});});// 声明供 App 调用的全局函数 window.msgFromUniApp=function(val){}; window.scanCodeFromUniApp=function(val){}; window.chooseImageFromUniApp=function(val){}; window.chooseVideoFromUniApp=function(val){};</script></body></html>
3.2.2 H5 业务页面(A.vue)
<template><div class="hello"><h3>H5内嵌页面</h3><!-- 扫一扫 --><van-field v-model="scanCode" label="扫一扫" placeholder="扫码结果"><template #button><van-button type="primary" size="small" @click="handleScan"> 扫一扫 </van-button></template></van-field><!-- 拨打电话 --><van-field v-model="phone" label="拨打电话"><template #button><van-button type="primary" size="small" @click="makePhoneCall"> 拨打 </van-button></template></van-field><!-- 蓝牙打印 --><div class="section"><van-button type="primary" size="small" @click="handleBluetoothPrint"> 蓝牙打印 </van-button></div><!-- 上传图片 --><div class="section"><div class="preview"><img v-for="item in fileList":key="item.url":src="item.url"/></div><van-button type="primary" size="small" @click="handleUploadImage"> 上传图片 </van-button></div><!-- 上传视频 --><div class="section"><div class="preview"><video v-for="item in videoList":key="item.url":src="item.url" controls /></div><van-button type="primary" size="small" @click="handleUploadVideo"> 上传视频 </van-button></div></div></template><script>exportdefault{data(){return{scanCode:'',phone:'13800138000',fileList:[],videoList:[]};},mounted(){// 重写全局回调,接收App执行结果 window.scanCodeFromUniApp=(val)=>{this.scanCode = val;}; window.chooseImageFromUniApp=(val)=>{this.fileList =this.fileList.concat(val);}; window.chooseVideoFromUniApp=(val)=>{this.videoList =this.videoList.concat(val);}; window.msgFromUniApp=(val)=>{ console.log('App主动消息:', val);};},methods:{// 统一消息发送入口postMessage(type, payload ={}){if(!window.uni ||!window.uni.webView){ console.error('uni.webView 未就绪');return;} window.uni.webView.postMessage({data:{ type,...payload }});},handleScan(){this.postMessage('scanCode');},makePhoneCall(){this.postMessage('phoneCall',{info:this.phone });},handleBluetoothPrint(){this.postMessage('bluetoothPrint',{info:[11,22]});},handleUploadImage(){this.postMessage('chooseImage',{options:{maxNumber:2,sourceTypeIndex:3,// 1:相机 2:相册 3:两者sizeTypeIndex:2,// 1:压缩 2:原图 3:两者url:'http://your-server/upload',bucketName:'jingsheng'}});},handleUploadVideo(){this.postMessage('chooseVideo',{options:{maxDuration:60,sourceTypeIndex:3,url:'http://your-server/upload',bucketName:'jingsheng'}});}}};</script>

四、关键注意事项

  • 本地 H5 调试:本地运行的 H5 页面需用Live Server打开,且地址需替换成本机
    IP(如192.168.1.4:5500),而非127.0.0.1,否则手机端无法访问;
  • App 端 webview 实例:必须通过this. s c o p e . scope. scope.getAppWebview()获取,且需延时 1
    秒左右确保实例创建完成;
  • 参数传递格式:通过evalJS传递复杂数据时,需用JSON.stringify序列化,避免语法错误;
  • 端兼容处理:通过#ifdef APP-PLUS/#ifdef H5区分不同端的通信逻辑,H5
    端需用window.postMessage,App 端用evalJS;
  • 权限申请:调用扫码、拨打电话、文件上传等功能时,需在manifest.json中配置对应权限。
  • App 端使用 uni.web-view.js 的最低版为 uni.webview.1.5.4.js

五、总结

  • UniApp 与 H5 的双向通信核心是:H5 通过uni.webView.postMessage发消息,UniApp 通过evalJS执行 H5 全局函数回传结果;
  • 需通过条件编译区分 App 端和 H5 端的通信逻辑,App 端依赖 webview 实例,H5 端依赖 window 对象;
  • 实际开发中需注意本地调试的 IP 替换、参数序列化、权限配置等细节,确保跨端通信稳定可靠。

通过这套方案,你可以轻松实现 UniApp 原生能力与 H5 页面的深度融合,既复用了 Web 端的开发成果,又能充分利用原生应用的功能优势。

Read more

2025:技术奇点前夜——AI重构世界,2026迈向智能纪元

2025:技术奇点前夜——AI重构世界,2026迈向智能纪元

2025年,人类站在技术奇点的门槛上。这一年,人工智能不再只是工具,而成为基础设施、生产力引擎与社会运行的新操作系统。从芯片到云边端,从代码到内容,从工厂到家庭,一场由AI驱动的深度重构悄然完成。回望2025,我们见证的不是渐进式演进,而是一场静默却彻底的范式转移;展望2026,一个以“智能原生”为底色的新纪元正加速开启。 一、2025:三大技术浪潮交汇,引爆产业质变 1. AI Agent 从概念走向规模化落地 2025年,大模型突破“问答机器”局限,进化为能自主规划、工具调用、多步执行的AI Agent。企业级Agent开始接管客服、运维、数据分析等重复性高、规则明确的任务。例如,某银行部署的信贷审核Agent,可自动调取征信、财报、舆情数据,生成风险评估报告,效率提升10倍,人力成本下降70%。 更关键的是,Agent开发框架(如LangChain、LlamaIndex)标准化,

2026最新实测:写小说软件到底哪家强?10款ai写小说神器硬核测评(附保姆级避坑指南)

2026最新实测:写小说软件到底哪家强?10款ai写小说神器硬核测评(附保姆级避坑指南)

说实话,今天这篇测评早就该发了。 作为在这个圈子里摸爬滚打多年的老码农,后台私信问得最多的就是:“大大,到底有没有靠谱的写小说软件?别推荐那种写出来全是翻译腔、逻辑稀碎的智障AI。” 我也懂大家的痛。市面上很多所谓的ai生成小说工具,写短文还凑合,一旦让它写长篇,角色名字乱变、剧情前后矛盾。为了帮大家避雷,我这次真把自己当小白鼠了,耗时两周,把目前市面上呼声最高的10款工具(笔灵、Claude、腾讯元宝、蛙蛙写作等)挨个试了个底朝天。 无论你是想找小说大纲范例超详细的模板,还是需要一个能日更万字的小说软件生成器,这篇测评都能让你少走弯路。 第一梯队:长篇创作与网文实战(强烈推荐) 1、笔灵AI写作 推荐指数: ⭐⭐⭐⭐⭐ 👉 传送门:https://ibiling.cn/novel-editor?from=ZEEKLOGnovellqyc1224(建议复制链接到电脑浏览器打开体验更佳!) ✅ 适合人群: 追求日更的网文作者、专注长篇的网文创作者、需要构建庞大世界观的写小说的人。 💡 实测体验: 这款工具必须放在第一个讲,因为它是目前我测下来,唯一一个可以解决我

编辑器中的AI革命:OpenClaw与Codex完全使用指南

前言:AI编程的新纪元 2026年,AI已经不再是简单的代码补全工具,而是能够真正"干活"的智能代理。今天我们来深入探讨两款最热门的编辑器AI工具——OpenClaw(龙虾)和OpenAI Codex,看看它们如何改变我们的编程方式。 一、OpenClaw(龙虾):会做事的AI助手 1.1 什么是OpenClaw? OpenClaw(曾用名Clawdbot/Moltbot)是一款本地优先的个人AI代理,采用龙虾🦞作为图标设计,口号是*"The AI that actually does things"*(真正做事的AI)。 核心特点: * ✅ 运行在本地设备上 * ✅ 支持10+消息平台(微信、Telegram、Discord、飞书等) * ✅ 可操作文件系统、终端、浏览器 * ✅ 开源免费,

【AI日报】每日AI最新消息2026-03-05

【AI日报】每日AI最新消息2026-03-05

最新 AI 新闻(2026-03-04 ~ 2026-03-05) 序号标题重要信息1阿里千问“灵魂人物”林俊旸突然卸任,核心团队现罕见人事震荡3 月 4 日凌晨,阿里 Qwen(通义千问)技术负责人林俊旸在社交平台发文“我卸任了,再见了亲爱的 Qwen”,后训练负责人郁博文、核心成员李凯新同日确认离职。报道指出,变动与通义实验室计划将千问团队从“垂直整合”拆分为水平分工团队、管理权被压缩有关,被视为阿里大模型路线的一次重要人事信号。2OpenAI 发布 GPT 5.3 Instant,谷歌同日推出 Gemini 3.1 Flash Lite 模型3 月 4 日,OpenAI 正式发布 GPT 5.3 Instant,重点优化网络搜索与对话体验,