微信小程序和webview通信踩坑(表单篇)

本文介绍了一种H5页面与小程序之间的地图选择功能交互方案。通过分析不同方案的可行性,最终选定在小程序内实现地图选择,并详细阐述了如何在H5与小程序间进行数据传递及状态同步。

背景

为了适配多端小程序,通用的功能一般采用webview的方式引入小程序,这次的移动管理端也不例外。

需求

h5表单的地图选择功能。如下所示:
webview地址选择需求
拉起地图

可行性分析

方案:

  1. 引入第三方地图
  2. 使用微信sdk的地图选择功能
  3. 采用跳转至小程序,使用小程序中的地图

分析:

  1. 方案一采用第三方地图在浏览器中没有问题,但是通过小程序的webview打开会出现提示无法打开该页面,大概率和小程序安全业务域名相关,先不考虑该做法。
  2. 方案二采用微信sdk直接拉起地图,但是经查询没有选择位置的方法,只有定位自身位置和打开地图的方法,也不考虑该做法。
  3. 方案三在小程序中单独写一个地图页面用来选择地图,选择完后进行和h5通信,实现该功能。(适合)

方案定为第三种,主要的难点在小程序和h5如何通信以及保留通信完成后原先填写的表单数据。

具体实现

  • webviewH5 --> miniProgram

通过js调用微信JSSDK的wx.miniProgram.navigateTo方法跳转到小程序的指定页面并且把参数当做query带给小程序原生页面。

  • miniProgram --> webviewH5

webview组件存在一个src属性, 用于展示指定的h5页面,通过操作当前src的hash值,当前组件上的页面是不会刷新的,webview的h5页面利用hashchange监听事件获取小程序传过来的值。

注意点:

  • webview 中的 console 并不会再微信开发者工具的控制台打印,alert才可以,打开了微信开发者工具中的 webview 的调试工具,那么 console和 alert 都不会执行。(大坑,开发效率特别低,建议不使用webview开发调试工具,只通过alert调试)
  • hash改变虽然当前组件上的页面是不会刷新的,但是js需要重新调用,也就是说useState会清空,form表单会清空。需要在跳转到小程序页面前保存当前的form所有的状态数据,可以保存在redux或者浏览器本地存储,在小程序跳转回h5的时候取出重新setState。
  • h5页面在跳转到小程序的时候将当前页面的完整url传递至小程序,实测获取当前h5页面完整url传递至小程序,query并不会成功,需要单独处理。

具体难点代码层面(Taro+react)

  • map页面具体实现
import Taro, {
   
    getCurrentPages, useRouter } from '@tarojs/taro';

const Map = () => {
   
   
  const {
   
    params } = useRouter();
  const {
   
    src, isParty, type, id } = useRouter().params; // 分别获取path以及所有的query
  Taro.getLocation({
   
   
    type: 'gcj02', //返回可以用于 Taro.openLocation的经纬度
    success: ({
    
     latitude, longitude }) => {
   
   
      Taro.chooseLocation({
   
   
        latitude,
        longitude,
        success: (res) => {
   
   
          const pages = 
### 微信小程序WebView通信方法及解决方案 微信小程序WebView之间的通信是开发中常见的需求之一,主要涉及H5页面与小程序的双向实时通信。以下是实现微信小程序WebView通信的具体方法示例代码。 #### 1. 使用 `postMessage` 实现单向通信微信小程序中,可以通过 `<web-view>` 组件的 `bindmessage` 事件来接收来自H5页面的消息。H5页面通过 `window.WeixinJSBridge.invoke('postMessage', { data: 'yourData' })` 向小程序发送消息[^2]。 ##### 示例代码: **小程序端:** ```html <web-view src="https://www.example.com" bindmessage="handleMessage"></web-view> ``` **小程序逻辑代码:** ```javascript Page({ handleMessage(e) { console.log('收到H5消息:', e.detail); // e.detail 包含 H5 发送的数据 } }); ``` **H5页面端:** ```javascript if (typeof WeixinJSBridge !== 'undefined') { WeixinJSBridge.invoke('postMessage', { data: 'Hello, Mini Program!' }); } else { document.addEventListener('WeixinJSBridgeReady', function () { WeixinJSBridge.invoke('postMessage', { data: 'Hello, Mini Program!' }); }, false); } ``` 需要注意的是,`postMessage` 的使用受到微信安全机制的限制,仅支持特定场景下的消息传递,例如页面退出、分享等[^1]。 --- #### 2. 使用 WebSocket 实现双向实时通信 为了实现更灵活的双向实时通信,可以考虑使用 WebSocket 技术。WebSocket 提供了全双工通信通道,允许H5页面与小程序之间进行实时数据交换。 ##### 示例代码: **服务器端(Node.js 示例):** ```javascript const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', (ws) => { ws.on('message', (message) => { console.log('收到客户端消息:', message); ws.send(`服务器已接收到: ${message}`); }); }); ``` **H5页面端:** ```javascript const socket = new WebSocket('ws://localhost:8080'); socket.onopen = () => { socket.send('Hello, Server!'); }; socket.onmessage = (event) => { console.log('收到服务器消息:', event.data); }; ``` **小程序端:** ```javascript const socket = wx.connectSocket({ url: 'ws://localhost:8080', }); socket.onOpen(() => { socket.send({ data: 'Hello, Server!' }); }); socket.onMessage((res) => { console.log('收到服务器消息:', res.data); }); ``` 通过 WebSocket,H5 页面与小程序可以实现实时的双向通信,但需要后端配合完成 WebSocket 服务的搭建[^1]。 --- #### 3. 使用 URL 参数或 LocalStorage 进行简单通信 如果通信需求较为简单,可以通过 URL 参数或 LocalStorage 来实现数据传递。 ##### 示例代码: **H5页面端:** ```javascript // 设置参数到 URL window.location.href = `https://example.com?data=HelloMiniProgram`; // 或者使用 LocalStorage localStorage.setItem('data', 'HelloMiniProgram'); ``` **小程序端:** 在小程序中解析 URL 参数或监听 LocalStorage 变化。 ```javascript Page({ onLoad(options) { console.log('从URL获取参数:', options.data); }, }); ``` 此方法适用于简单的单向通信场景,但对于复杂或实时性要求较高的场景并不适用[^3]。 --- #### 4. 使用 Uni-app 的 `uni.webview` 方法 如果项目基于 Uni-app 开发,可以利用 `uni.webview` 提供的接口实现更便捷的通信功能。例如,通过 `uni.postMessage` 方法直接向 WebView 内嵌的 H5 页面发送消息。 ##### 示例代码: **小程序端:** ```javascript uni.postMessage({ data: { message: 'Hello, H5!' } }); ``` **H5页面端:** ```javascript window.addEventListener('message', (event) => { console.log('收到小程序消息:', event.data); }); ``` 这种方法适用于 Uni-app 环境下的开发,提供了更简洁的 API 调用方式[^4]。 --- ### 注意事项 - 微信小程序的安全策略对 `<web-view>` 的使用有严格限制,确保通信内容符合平台规范。 - 如果需要更复杂的交互逻辑,建议结合后端服务实现数据中转。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值