飘易博客(作者:Flymorn)
订阅《飘易博客》RSS,第一时间查看最新文章!
飘易首页 | 留言本 | 关于我 | 订阅Feed

微信小程序开发之webview实战

Author:飘易 Source:飘易
Categories:微信开发 PostTime:2019-9-20 21:35:58
正 文:

微信小程序推出后,微信之父张小龙曾公开表态说:“小程序未来能取代百分之八十的app。”


小程序不需要下载安装,直接在打开的微信当中搜一搜中进行搜索或者扫描二维码,点击打开就好。小程序全面开放申请后,主体类型为企业、政府、媒体、其他组织或个人的开发者,均可以申请注册小程序。小程序、订阅号、服务号、企业号是并行的体系。


小程序的优点

微信小程序在其成长过程中,虽然一直饱受争议,但是微信小程序的确拥有不占内存、入口场景丰富、流量红利大、支持付费推广、可关联公众号等优点。


在很多推广活动中要求客户安装APP才能享受福利,想得到福利就必须得安装APP,这样就会引起客户的反感,一是嫌麻烦,二是安装APP占用的内存太大,若是手机内存根本不够用,更不愿安装APP。但是用小程序就不会出现这样的问题。小程序在不使用的时候不占用微信存储空间更不占用手机的存储空间。

对于开发者来说,小程序更容易开发,耗时短而且bug少,这一点对于程序员来说是最有认同感的吧。一个APP的开发需要三个月,四个月,甚至五个月,小程序的开发是不需要这么长时间的,这一点对于一些刚起步的创业者来说是很有利的,开发成本小且等待时间短。


小程序瞄准的是“轻量级服务”,所以小程序能做到的是“满足用户大部分的基础需求”。


为什么要使用小程序的webview?


很多时候,我们的产品不仅一个端口,有APP、H5、小程序,特别是对于一些混合开发的webapp来说,H5已经开发好了,那么小程序是否一定要重新开发呢?如果重新开发,那么还有支付宝小程序、头条小程序、百度小程序等小程序们,难道要一个个的针对开发吗?  又或者,你只熟悉传统的H5开发方式,不想花太多的精力去开发原生的小程序呢?


幸好,这些小程序提供了webview组件,对于大部分的功能来说,我们可以用使用webview组件来承载H5页面,H5页面不支持的无法实现的功能再使用原生小程序页面来开发。


webview支持哪些功能

web-view是从基础库 1.6.4 开始支持,低版本需做兼容处理。webview是承载网页的容器,自动铺满整个小程序页面,个人类型与海外类型的小程序暂不支持使用。

客户端 6.7.2 版本开始,navigationStyle: custom 对 <web-view> 组件无效,也就意味着你不能去掉顶部的导航栏。


<web-view/>网页中可使用JSSDK 1.3.2提供的接口返回小程序页面。 支持的接口有:


接口名说明最低版本
wx.miniProgram.navigateTo参数与小程序接口一致1.6.4
wx.miniProgram.navigateBack参数与小程序接口一致1.6.4
wx.miniProgram.switchTab参数与小程序接口一致1.6.5
wx.miniProgram.reLaunch参数与小程序接口一致1.6.5
wx.miniProgram.redirectTo参数与小程序接口一致1.6.5
wx.miniProgram.postMessage向小程序发送消息,会在特定时机(小程序后退、组件销毁、分享)触发组件的message事件1.7.1
wx.miniProgram.getEnv获取当前环境



<web-view/>网页中仅支持以下JSSDK接口

接口模块接口说明具体接口
判断客户端是否支持js
checkJSApi
图像接口拍照或上传chooseImage

预览图片previewImage

上传图片uploadImage

下载图片downloadImage

获取本地图片getLocalImgData
音频接口开始录音startRecord

停止录音stopRecord

监听录音自动停止onVoiceRecordEnd

播放语音playVoice

暂停播放pauseVoice

停止播放stopVoice

监听语音播放完毕onVoicePlayEnd

上传接口uploadVoice

下载接口downloadVoice
智能接口识别音频translateVoice
设备信息获取网络状态getNetworkType
地理位置使用内置地图打开地点openLocation

获取地理位置getLocation
摇一摇周边开启ibeaconstartSearchBeacons

关闭ibeaconstopSearchBeacons

监听ibeacononSearchBeacons
微信扫一扫调起微信扫一扫scanQRCode
微信卡券拉取使用卡券列表chooseCard

批量添加卡券接口addCard

查看微信卡包的卡券openCard
长按识别小程序圆形码

特别提醒:

  • tip:网页内 iframe 的域名也需要配置到域名白名单。

  • tip:开发者工具上,可以在 <web-view/> 组件上通过右键 - 调试,打开 <web-view/> 组件的调试。

  • tip:每个页面只能有一个 <web-view/>,<web-view/> 会自动铺满整个页面,并覆盖其他组件。

  • tip:<web-view/> 网页与小程序之间不支持除 JSSDK 提供的接口之外的通信。

  • tip:在 iOS 中,若存在JSSDK接口调用无响应的情况,可在 <web-view/> 的 src 后面加个#wechat_redirect解决。

  • tip:避免在链接中带有中文字符,在 iOS 中会有打开白屏的问题,建议加一下 encodeURIComponent


webview不支持的功能

除了上面列出的支持的功能外,其他的均不能使用webview实现,从微信的角度来说,微信也是不鼓励大家过多的使用webview,微信的本意是让开发者将webview仅作为一个辅助,以便方便的加载一些H5页面。


不支持的功能

  • 微信登录、用户授权

  • 微信支付

  • 视频拍摄、选择、上传

  • 背景音频

  • 实时音视频(直播)

  • 地理位置的实时监听、选取

  • 转发分享

  • UDP通信

  • 原生文件交互能力

  • 权限设置

  • 收货地址、发票

  • 生物认证

  • 微信运动

  • 设备功能(wifi、ibeacon、蓝牙、NFC等硬件交互能力)

  • 更多...


如果你的项目里必须要使用上述的这些功能,那么狠抱歉,webview不支持!


webview导航栏的返回按钮

如果我们把webview直接放在小程序的首页里,那么你会发现H5页面只能一个链接接着一个往下点,不能返回到上一页(安卓有系统Home返回,但苹果没有),导航栏左边的返回箭头是不会出现的,因为按照小程序的逻辑,首页是不需要返回按钮的。


怎么破?我们可以把webview放到第2个页面,小程序的首页 /pages/index/index 直接跳转到 /pages/webview/webview 页面,这下webview页面顶部就会出现返回的箭头了,这个箭头和我们浏览器的后退按钮功能类似,在webview里不断点击链接后,可以正常的逐级返回到前面的页面里。


/pages/index/index.js 代码实现:

//index.js
//获取应用实例
const app = getApp()

Page({
   data: {
       enterTime: 0, // 进入主页时间戳
       isFirst: true,
       exitApp: false
   },

   /**
     * 跳转到内页
     */
   redirect: function() {       
           wx.navigateTo({
               url: '/pages/webview/webview'
           })
   },

   /**
     * 生命周期函数--监听页面显示
     */
   onShow() {
       var _this = this;

       // 首次进入
       if (this.data.isFirst) {
           this.data.isFirst = false;
           _this.redirect(); // 跳转到内页
       } else {
           // 判断N秒钟内是否连续两次返回到主页,若是则退出
           if (this.data.enterTime == 0) {
               this.data.enterTime = new Date().getTime();
               setTimeout(function() {
                   _this.data.enterTime = 0;
               }, 3000);
               // 不显示过渡页面
               _this.setData({
                   exitApp: false
               });
               _this.redirect(); // 跳转到内页
           } else if (new Date().getTime() - this.data.enterTime < 3000) {
               _this.data.enterTime = 0;
               // 显示过渡页面
               _this.setData({
                   exitApp: true
               });
           }else{
               _this.data.enterTime = 0;
               // 不显示过渡页面
               _this.setData({
                   exitApp: false
               });
               _this.redirect(); // 跳转到内页
           }
       };
   }

})


index.wxml 代码实现:

<!--index.wxml-->
<view wx:if="{{exitApp}}" class="box">
   <view>
       <image class="logo" mode="aspectFit" src="../images/logo.png"></image>
   </view>
   <view class="title_box">
       <text class="title">非著名老友社</text>
   </view>

   <navigator open-type="navigate" target="navigate" url='/pages/webview/webview' class="continue">继续浏览</navigator>
   <navigator open-type="exit" target="miniProgram" class="close">关闭小程序</navigator>
</view>

这个页面其实是一个过渡关闭的页面,当安卓手机在3秒钟内连续2次返回到首页的时候,将显示当前页面里的元素,主要有2个navigator,一个是继续浏览按钮,一个是关闭当前小程序的按钮,这样做的目的是:

1、安卓手机返回到首页的时候,再按一次home键,就可以直接退出小程序了;

2、用户也可以点击页面里面的2个按钮,选择继续访问或者关闭当前小程序;

3、苹果手机的用户体验和安卓的保持一致。


/pages/webview/webview.js 页面代码:

// pages/webview/webview.js
var app = getApp();

Page({

   /**
     * 页面的初始数据
     */
   data: {
       url: '',
       rnd: (new Date()).valueOf(),// 时间戳
   },
   
   /**
     * 生命周期函数--监听页面加载
     */
   onLoad: function(options) {
       var _this = this;
       console.log("webview onLoad")
       console.log(options, _this.data.rnd)
       _this.setData({
           url: 'https://www.piaoyi.org/?r=' + _this.data.rnd
       });
   },

   /**
     * 生命周期函数--监听页面显示
     */
   onShow: function() {
       // 分享设置
       wx.showShareMenu({
           withShareTicket: true
       })
   },

   /**
     * 用户点击右上角分享
     */
   onShareAppMessage: function(options) {
       console.log('onShareAppMessage', options)
       // 特别注意这里,配置分享链接一定要给首页链接,要不然别人点进来又是没有返回按钮的哦
       return {
           title: '非著名老友社',
           path: '/pages/index/index' // 分享出去后打开的页面地址
       }
   },

})


/pages/webview/webview.wxml:

<!--pages/webview/webview.wxml-->

<web-view src="{{ url }}"></web-view>


webview与小程序之间的实时通信

  • webview主动发消息给小程序

webview可以利用jssdk提供的 wx.miniProgram.postMessage 接口发送消息给小程序,但是请注意,小程序不是实时处理这个消息的,仅在小程序后退、组件销毁、分享这三种情况下处理收到的消息。飘易在社区里看到有人利用 wx.miniProgram.navigateBack 这个接口主动触发小程序的后退,以便能处理消息这样的以毒攻毒的方法,但飘易觉的不稳妥,因为你要非常小心地处理小程序的后退问题。


  • 小程序主动发消息给webview

小程序主动发消息,相对简单,只需要给webview的 src 赋值就可以了,可以传递参数过去,然后H5页面收到参数再处理就好。但是如果设置的url和上一次不同,webview会重新刷新加载,而对于一些单页面应用来说,webview是不能刷新的,那么我们还有一个方法,可以给url加上锚链接 #,然后通过监听 onhashchange  事件来判断锚链接是否发生变化。


但是,很不巧,飘易的项目本身已经是单页面应用,在链接里已经用上了锚链接 #&,因此再利用锚链接传递参数会导致原先的单页面找不到页面的错误。


此路不通。


  • 利用websocket实现小程序和webview的实时通信

小程序支持websocket,H5页面里js也支持websocket,而websocket是实时双向通信的,因此我们只要搭建一套websocket的服务作为中间件,供H5和小程序同时调用,就可以解决这2者之间的实时通信的问题。


比如,当我们在原生小程序里上传视频完成后,我们可以把视频地址通过websocket服务器转发到H5页面的websocket,然后H5页面把视频路径拼接并显示,完成我们整个交互的流程。


这种方式的缺点是当网络不太稳定的时候,客户端可能收不到信息。


其他问题

  • webview里不能同时使用动态 src 和 wx:if 条件表达式;

  • webview的缓存问题:

    1、可以给src加上一个时间戳,然后给引用的js和css文件加上不同的版本号,以便让缓存失效,加载最新的数据;

    2、对于顽固的缓存,可以退出微信账号登录,再登录进去,刷新缓存。

  • webview在iOS系统下video全屏bug

    在iOS下的特定版本(iOS12),如果使用html5的video标签,全屏后再缩小,这个时候,顶部的导航栏上的状态文字(时间、网络信号、电池电量这行)会显示不出来,成了白底白字;但是升级了iOS13后,状态栏文字颜色是正常的白底黑字。



【参考】:

* 微信小程序官方开发文档

* 微信小程序 web-view 容器介绍

小程序中h5页面onShow实现及跨页面通信方案

作者:飘易
来源:飘易
版权所有。转载时必须以链接形式注明作者和原始出处及本声明。
上一篇:微信小程序开发之授权权限管理
下一篇:乐鑫ESP8266使用MQTT-AT固件连接乐为物联网
0条评论 “微信小程序开发之webview实战”
No Comment .
发表评论
名称(*必填)
邮件(选填)
网站(选填)

记住我,下次回复时不用重新输入个人信息
© 2007-2019 飘易博客 Www.Piaoyi.Org 原创文章版权由飘易所有