在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

news2025/6/12 16:27:04

uni-app 中 Web-view 与 Vue 页面的通讯机制详解

一、Web-view 简介

Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面:

  • 支持加载本地 HTML 文件
  • 支持加载远程 HTML 页面
  • 实现 Web 与原生的双向通讯
  • 可用于嵌入第三方网页或 H5 应用
二、Web-view 加载 HTML 的方式
1. 加载本地 HTML 文件
<template>
  <view>
    <web-view :src="localHtmlPath"></web-view>
  </view>
</template>

<script setup>
import { ref, onLoad } from 'vue';

const localHtmlPath = ref('');

onLoad(() => {
  // 本地 HTML 文件路径
  localHtmlPath.value = '/static/html/index.html';
});
</script>
2. 加载远程 HTML 页面
<template>
  <view>
    <web-view :src="remoteUrl"></web-view>
  </view>
</template>

<script setup>
import { ref, onLoad } from 'vue';

const remoteUrl = ref('');

onLoad(() => {
  // 远程 HTML 页面 URL
  remoteUrl.value = 'https://www.example.com';
});
</script>
三、Web-view 与 Vue 页面的通讯方式
1. H5 页面向 uni-app 发送消息

在 H5 页面中:

// H5 页面 (index.html)
function sendMessageToUniApp() {
  // 方式一:使用 postMessage (推荐)
  window.uni.postMessage({
    type: 'getData',
    data: {
      name: '张三',
      age: 25
    }
  });
  
  // 方式二:使用自定义 JSBridge (兼容旧版本)
  if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.uni) {
    // iOS 平台
    window.webkit.messageHandlers.uni.postMessage({
      type: 'getData',
      data: {
        name: '张三',
        age: 25
      }
    });
  } else if (window.uni) {
    // Android 平台
    window.uni.postMessage(JSON.stringify({
      type: 'getData',
      data: {
        name: '张三',
        age: 25
      }
    }));
  }
}

在 uni-app 页面中接收消息:

<template>
  <view>
    <web-view :src="htmlPath" @message="handleMessage"></web-view>
  </view>
</template>

<script setup>
import { ref } from 'vue';

const htmlPath = ref('/static/html/index.html');

const handleMessage = (e) => {
  const data = e.detail.data[0];
  console.log('收到 H5 消息:', data);
  
  // 根据消息类型处理
  if (data.type === 'getData') {
    // 处理数据
    console.log('用户信息:', data.data);
  }
};
</script>
2. uni-app 向 H5 页面发送消息

在 uni-app 页面中:

<template>
  <view>
    <button @click="sendToH5">向 H5 发送消息</button>
    <web-view ref="webviewRef" :src="htmlPath"></web-view>
  </view>
</template>

<script setup>
import { ref } from 'vue';

const webviewRef = ref(null);
const htmlPath = ref('/static/html/index.html');

const sendToH5 = () => {
  // 向 H5 发送消息
  webviewRef.value.postMessage({
    type: 'setData',
    data: {
      title: '来自 uni-app 的数据',
      content: '这是一条从 uni-app 发送到 H5 的消息'
    }
  });
};
</script>

在 H5 页面中接收消息:

// H5 页面 (index.html)
// 监听 uni-app 发送的消息
window.addEventListener('message', (e) => {
  const data = e.data;
  console.log('收到 uni-app 消息:', data);
  
  // 根据消息类型处理
  if (data.type === 'setData') {
    // 更新页面内容
    document.getElementById('title').innerText = data.data.title;
    document.getElementById('content').innerText = data.data.content;
  }
});
四、在 H5 页面中调用 uni-app API
1. 使用 postMessage 间接调用

在 H5 页面中:

// H5 页面 (index.html)
function callUniAppAPI() {
  // 请求调用 uni-app API
  window.uni.postMessage({
    type: 'callAPI',
    apiName: 'getLocation',
    params: {
      type: 'wgs84'
    }
  });
}

在 uni-app 页面中:

<template>
  <view>
    <web-view :src="htmlPath" @message="handleMessage"></web-view>
  </view>
</template>

<script setup>
import { ref } from 'vue';

const htmlPath = ref('/static/html/index.html');
const webviewRef = ref(null);

const handleMessage = (e) => {
  const data = e.detail.data[0];
  
  // 处理 API 调用请求
  if (data.type === 'callAPI') {
    const { apiName, params } = data;
    
    // 根据 API 名称调用相应的 uni-app API
    if (apiName === 'getLocation') {
      uni.getLocation({
        ...params,
        success: (res) => {
          // 将结果返回给 H5 页面
          webviewRef.value.postMessage({
            type: 'apiResult',
            apiName,
            success: true,
            result: res
          });
        },
        fail: (err) => {
          // 将错误返回给 H5 页面
          webviewRef.value.postMessage({
            type: 'apiResult',
            apiName,
            success: false,
            error: err
          });
        }
      });
    }
    // 可以添加更多 API 的处理
  }
};
</script>

在 H5 页面中接收 API 结果:

// H5 页面 (index.html)
window.addEventListener('message', (e) => {
  const data = e.data;
  
  // 处理 API 调用结果
  if (data.type === 'apiResult') {
    if (data.success) {
      console.log('API 调用成功:', data.result);
      // 更新页面显示
      document.getElementById('location').innerText = `纬度: ${data.result.latitude}, 经度: ${data.result.longitude}`;
    } else {
      console.error('API 调用失败:', data.error);
      // 显示错误信息
      document.getElementById('location').innerText = '获取位置失败';
    }
  }
});
2. 使用 JSBridge 直接调用

在 uni-app 页面中注入 JSBridge:

<template>
  <view>
    <web-view ref="webviewRef" :src="htmlPath" @message="handleMessage"></web-view>
  </view>
</template>

<script setup>
import { ref, onReady } from 'vue';

const webviewRef = ref(null);
const htmlPath = ref('/static/html/index.html');

onReady(() => {
  // 注入 JSBridge
  const jsStr = `
    window.uniAPI = {
      getLocation: function(callback) {
        window.uni.postMessage({
          type: 'callAPI',
          apiName: 'getLocation',
          callbackId: 'getLocation_' + Date.now()
        });
        
        // 存储回调函数
        window.uniAPI._callbacks['getLocation_' + Date.now()] = callback;
      },
      _callbacks: {}
    };
  `;
  
  // 执行 JS 代码注入 JSBridge
  webviewRef.value.evalJs(jsStr);
});

const handleMessage = (e) => {
  const data = e.detail.data[0];
  
  // 处理 API 调用结果
  if (data.type === 'apiResult') {
    const callback = window.uniAPI._callbacks[data.callbackId];
    if (callback) {
      callback(data.success ? data.result : null, data.success ? null : data.error);
      delete window.uniAPI._callbacks[data.callbackId];
    }
  }
};
</script>

在 H5 页面中使用 JSBridge:

// H5 页面 (index.html)
function getLocation() {
  // 使用 JSBridge 调用 uni-app API
  window.uniAPI.getLocation((result, error) => {
    if (result) {
      console.log('获取位置成功:', result);
      document.getElementById('location').innerText = `纬度: ${result.latitude}, 经度: ${result.longitude}`;
    } else {
      console.error('获取位置失败:', error);
      document.getElementById('location').innerText = '获取位置失败';
    }
  });
}
五、注意事项与最佳实践
  1. 跨域问题

    • 加载远程 HTML 时需确保域名在白名单中
    • manifest.json 中配置 h5domains
  2. 性能优化

    • 避免频繁通讯
    • 使用批量数据传输
    • 对数据进行压缩处理
  3. 安全考虑

    • 验证消息来源
    • 对敏感操作进行权限控制
    • 避免在 URL 中传递敏感信息
  4. 兼容性处理

    • 处理不同平台的差异
    • 提供降级方案
    • 进行充分测试
  5. 调试技巧

    • 使用 HBuilderX 的调试工具
    • 在 H5 页面中添加日志输出
    • 使用浏览器开发者工具调试
六、常见问题解决方案
  1. 消息接收不及时

    • 确保 web-view 组件已加载完成
    • 使用定时器重试机制
  2. API 调用失败

    • 检查 API 名称和参数是否正确
    • 确认 API 权限是否已获取
    • 处理 API 调用超时情况
  3. 内存泄漏

    • 及时清理不再使用的回调函数
    • 避免创建过多的临时对象
    • 合理管理消息队列
  4. 性能问题

    • 减少跨边界通讯次数
    • 批量处理数据
    • 对大数据进行分片传输

通过以上方法,您可以在 uni-app 中实现 Web-view 与 Vue 页面的高效通讯,为用户提供更丰富的交互体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2407400.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…