likes
comments
collection
share

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

作者站长头像
站长
· 阅读数 3

前言:

最近做的微信小程序项目,有个需求是:微信小程序中webView内嵌的H5页面中,有多种格式的文件(包括pdf、doc、Excel、mp4、png等)需要支持在微信小程序中打开预览。

一、项目需求简介

微信小程序项目中webView内嵌了一个H5页面,这个H5页面同时也内嵌在App应用(包括安卓和iOS)中,所以需要在H5页面中判断是否是在微信小程序中,只有在小程序中才触发这个传值交互。 H5页面中会展示文件目录,点击可以打开对应的文件。 所以,需要做到:如果在App中,则调用App原生的方法打开文件;如果在微信小程序中,需要调用小程序预览文件的功能。

二、微信小程序中webView的H5页面,并传值给H5

  1. 微信小程序中的入口页面,如下图:

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

<view bindtap="toMaintenanceInfoPage" data-id="{{item.id}}" data-name="{{item.name}}" data-index="{{itemIndex}}" class="content">
</view>

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

methods: {
  // 跳转至详情
  toMaintenanceInfoPage(e) {
    const data = e.currentTarget.dataset;
    app.globalData.maintenanceCenterIndex = e.currentTarget.dataset.index;
    const token = wx.getStorageSync('token');
    const url = api.nspUrl;
    wx.navigateTo({
      url: `/pages/webViewPage/webViewPage?url=${url}&token=${token}&id=${data.id}&name=${data.name}`,
    })
  }
}

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

  1. 微信小程序中的webView页面,如下图:

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

<view class="container">
  <web-view wx:if="{{url}}" src="{{url}}"></web-view>
</view>

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

onLoad: function (options) {
    if (options.token) {
      this.setData({
        url: `${options.url}?token=${options.token}&id=${options.id}`,
        name: options.name,
        token: options.token,
        id: options.id,
      })
    }
},

这样就已经在微信小程序中完成了嵌套H5页面的功能。

三、点击H5页面中的文件,调用小程序原生预览文件功能

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

<p class="title">内部资料</p>
<div class="dataList">
  <div v-for="(item, index) in detailData.knowledgeAttachmentList" :key="index" class="item">
    <span @click="toAppDownload(item)">{{item.name}}.{{item.attachmentSuffix}}</span>
  </div>
</div>

H5传值:

  1. 点击之后,H5判断是否是在微信小程序中,因为H5不止在小程序中嵌套,还可以在App中打开,或者可以单独在浏览器中打开,所以只有在小程序中才触发这个传值:
// 判断是否在微信环境
const isWeixin = /MicroMessenger/i.test(navigator.userAgent);
// 判断是否在微信小程序环境
const isMiniProgram = /miniProgram/i.test(navigator.userAgent.toLowerCase());
  1. H5传值,需要实现H5页面跳转到小程序的某个页面,所以要先安装小程序的sdk,我这边是vue项目,安装步骤如下:
  • 先安装依赖
// 安装依赖
npm install weixin-js-sdk
  • 然后引入依赖
// 引入依赖
import wx from 'weixin-js-sdk';
  • H5使用依赖进行跳转:从H5页面中获取文件的URL和文件name,然后跳转到指定的小程序页面,并将这俩参数传到小程序中。
if (isWeixin && isMiniProgram) { // 如果在小程序内打开文件
  wx.miniProgram.navigateTo({
    url: `/pages/previewPage/previewPage?source=wap&url=${newUrl}&name=${name}`,
  });
}

说明:

此处跳转到小程序页面的原因是:

  1. 我们后端返回的文件URL是华为云自动生成的,域名虽然是固定的,但是域名下没有对应的项目,所以没有办法在域名下放置微信小程序要求的配置文件。如果能放配置文件的域名,此处是可以直接跳转到webViewPage页面的。
  2. 没有用wx.miniProgram.postMessage({ data:postData });,是因为只有用户点击了小程序的后退、分享按钮或者是小程序嵌入的H5页面销毁才能触发参数的传递,否则不会触发。 显然这个接口满足不了我的需求。 参考链接:web-view相关接口

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

四、微信小程序接收值

小程序previewPage页面接收值,并在onLoad时打开:

onLoad: function (options) {
  if (options.source && options.source === 'wap') { // 如果是在小程序内打开文件
    this.wxDownLoad(options);
  }
},

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

如果文件类型为pdf、xlsx、doc等时的打开方式:

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

wxDownLoad(options) {
    wx.showLoading({
      title: '正在打开...',
    });
    wx.downloadFile({
      url: options.url,
      filePath: wx.env.USER_DATA_PATH + "/" + decodeURIComponent(options.name), // 设置自定义标题
      success: (res) => {
        if (res.statusCode === 200) {
          const filePath = res.filePath;
          wx.openDocument({
            showMenu: true,
            filePath: filePath,
            success: function (res) {
              wx.hideLoading();
            },
            fail: function (res) {
            }
          })
        }
      },
    })
  }

如果文件类型是视频或图片(mp4/png、jpg等)时,需要判断文件后缀,做不同的操作:

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

// 获取文件后缀
const suffix = options.url.substr(options.url.lastIndexOf("."));

if (suffix.indexOf('png') > -1 || suffix.indexOf('jpg') > -1 || suffix.indexOf('jpeg') > -1) {
  that.setData({ imgUrl: options.url });
} else if (suffix.indexOf('mp4') > -1) {
  that.setData({ videoUrl: options.url })
}

微信小程序中webView的H5页面与小程序双向通信,调用微信小程序预览文件功能

<view class="container">
  <video wx:if="{{videoUrl}}" class="video" src="{{videoUrl}}" show-mute-btn="true" ></video>
  <image wx:elif="{{imgUrl}}" src="{{imgUrl}}" data-url="{{imgUrl}}" bindtap="fnPreviewImage" class="avatarImg" mode="widthFix"></image>
</view>

这样就实现了微信小程序与内嵌webView的H5页面的双向通信,并且也能在webview中预览各种格式的文件。

以上,希望对大家有帮助!