彩世界平台-彩世界时时app-彩世界开奖app苹果下载

热门关键词: 彩世界平台,彩世界时时app,彩世界开奖app苹果下载

您的位置:彩世界平台 > 新闻动态 > 微信小程序web-view

微信小程序web-view

发布时间:2019-11-15 06:15编辑:新闻动态浏览(131)

    网页程序迁移至微信小程序web-view详解

    2018/08/02 · JavaScript · 小程序

    原文出处: NeoPasser   

    小程序现在越来越流行,但是公司的很多项目都是用网页写的,小程序语法不兼容原生网页,使得旧有项目迁移至小程序代价很高。

    小程序之前开放了webview功能,可以说是网页应用的一大福音了,但是微信的webview有一些坑,这篇文章就是列举一下我在开发过程中遇到的一些问题以及我找到的一些解决方案。

    基于公司业务需求,在做Android开发的同时,还得同步进行另一个项目的微信小程序开发,没办法,公司调整,节约成本,研发也减少了不少人,只得边学边开发...

    遇到的问题

    1. openid登录问题
    2. webview动态src
    3. 支付功能
    4. 分享功能
    5. 扫描普通二维码跳转特定页面
    6. 返回按钮缺失问题

    不过微信11月发布了小程序支持web-view的消息,让本次开发减了不少的工作量,主要是蓝牙设备的数据采集及上传

    openid登录问题

    微信webview的使用方法很简单,只要如下设置src就可以展示具体的网站了。

    <!-- wxml --> <!-- 指向微信公众平台首页的web-view --> <web-view src=";

    1
    2
    3
    <!-- wxml -->
    <!-- 指向微信公众平台首页的web-view -->
    <web-view src="https://mp.weixin.qq.com/"></web-view>

    微信环境里的很多网页都是用页面要实现网站的登录功能,只要把登录的信息,比如openid或者其他信息拼接到src里就好了。

    这里有个问题,公众号的账号体系一般是以openid来判断唯一性的,小程序是可以获取openid的,但是小程序的openid和原公众号之类的openid是不一样的,需要将原先的openid账号体系升级为unionid账号体系。

    以下是微信对unionid的介绍

    获取用户基本信息(UnionID机制)

    在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。

    请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。

    UnionID机制说明:

    开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

    做完以上步骤,就可以调用小程序api wx.getUserInfo() 来获取用户信息了,此步骤需要进行后台信息解密过程,在此就不再赘述,结合小程序api文档操作就好。

    获取到unioid之后,将unionid信息拼接到src就可以进行网页登录操作了(前提是网页可以用跳转链接的方式登录,类似公众号页面获取openid的形式)。

    • web-view

    webview动态src

    微信的webview有个坑的地方,不会动态的监听src的变化,这就造成了一个问题,要通过改变src实现页面跳转就不可以了。
    我尝试了一些方法之后,找到了一个解决方案:

    微信webview在页面load的时候会加载一次webview,我们就利用这个特性来实现动态src问题。

    1. 首先把要跳转的链接信息设置成全局变量,要改变src的时候,先把要src以’?‘拆分为链接和参数两部分,存入全局函数,再调用onLoad就可以实现webview刷新了。
    2. 页面跳转时,我们也需要src的动态刷新,所以要把链接信息存入全局函数;页面跳转时,onShow函数会被调用,这时候再调用一次onLoad就可以了。

    data: { url: '', loaded: false } // 小程序js里的onLoad函数可以写成这样 onLoad: function () { this.setData({ url: getApp().globalData.urlToken + '?' + getApp().globalData.urlData }) }, changUrl: function () { getApp().globalData.urlToken = '' getApp().globalData.urlToken = 'a=1&b=2' // 直接调用onLoad,就会实现src的刷新 this.onLoad() }, onShow: function () { if (!this.data.loaded) { // 第一次不运行 this.setData({ loaded: true }) return } // 直接调用onLoad,就会实现src的刷新 this.onLoad() } // wxml可以写成这样 <web-view src="{{url}}"></web-view>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    data: {
        url: '',
        loaded: false
    }
    // 小程序js里的onLoad函数可以写成这样
    onLoad: function () {
        this.setData({
          url: getApp().globalData.urlToken + '?' +  getApp().globalData.urlData
        })
    },
    changUrl: function () {
        getApp().globalData.urlToken = 'https://www.example.com'
        getApp().globalData.urlToken = 'a=1&b=2'
        // 直接调用onLoad,就会实现src的刷新
        this.onLoad()
    },
    onShow: function () {
        if (!this.data.loaded) {
          // 第一次不运行
          this.setData({
            loaded: true
          })
          return
        }
        // 直接调用onLoad,就会实现src的刷新
        this.onLoad()
      }
     
    // wxml可以写成这样
    <web-view src="{{url}}"></web-view>

    于是,就去了解了一下web-view

    支付功能

    webview里面可以通过jssdk来实现一些小程序功能,但不能直接调用小程序的支付功能,这时候我们就需要转变一下策略了:

    1. 在网页里引入微信jssdk
    2. 在网页需要发起支付的地方,调用跳转页面的接口,控制小程序跳转到小程序的支付页面(这个要在小程序里单独写的),跳转的时候,需要把订单的一些信息都拼接到链接里,订单信息由后台返回,需要通过微信支付系统的统一下单接口,具体参看支付文档。
    3. 跳转到小程序支付页面后,由小程序页面发起支付,支付完成后跳转回webview页面,通过之前设置的动态src,控制webview跳转到特定的页面。

    JavaScript

    // 网页引入jssdk // 网页发起支付 wx.miniProgram.navigateTo({ // payData由后台返回,主要是需要统一下单平台的prepay_id url: '../pay/index?data=' + encodeURIComponent(JSON.stringify(payData)) }) // 微信支付页面 onLoad: function (option) { let page = this try { let data = JSON.parse(option.data) if (!data || !data.prepay_id) { console.error('支付参数错误,请稍后重试', data) } wx.requestPayment({ timeStamp: '' + data.timestamp, nonceStr: data.nonceStr, package: 'prepay_id=' + data.prepay_id, paySign: data.paySign, signType: data.signType, success: function (res) { getApp().globalData.urlToken = `paySuccess.html` // 支付成功 getApp().globalData.urlData = 'data=paySuccessData' wx.navigateTo({ url: '/page/home/index', }) }, fail: function (res) { getApp().globalData.urlToken = `payError.html` // 支付失败 getApp().globalData.urlData = 'data=payErrorData' wx.navigateTo({ url: '/page/home/index', }) }, complete: function (res) { } }) } catch (e) { console.error('支付错误', e) } }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    // 网页引入jssdk
     
    // 网页发起支付
    wx.miniProgram.navigateTo({
        // payData由后台返回,主要是需要统一下单平台的prepay_id
        url: '../pay/index?data=' + encodeURIComponent(JSON.stringify(payData))
    })
    // 微信支付页面
    onLoad: function (option) {
        let page = this
        try {
          let data = JSON.parse(option.data)
          if (!data || !data.prepay_id) {
            console.error('支付参数错误,请稍后重试', data)
          }
          wx.requestPayment({
            timeStamp: '' + data.timestamp,
            nonceStr: data.nonceStr,
            package: 'prepay_id=' + data.prepay_id,
            paySign: data.paySign,
            signType: data.signType,
            success: function (res) {
              getApp().globalData.urlToken = `paySuccess.html`
              // 支付成功
              getApp().globalData.urlData = 'data=paySuccessData'
              wx.navigateTo({
                url: '/page/home/index',
              })
            },
            fail: function (res) {
              getApp().globalData.urlToken = `payError.html`
              // 支付失败
              getApp().globalData.urlData = 'data=payErrorData'
              wx.navigateTo({
                url: '/page/home/index',
              })
            },
            complete: function (res) {
            }
          })
        } catch (e) {
          console.error('支付错误', e)
        }
      }
    1. 个人开发者无法使用
    2. 需要配置域名,且域名需ICP备案24小时以上,不支持ip及端口
    3. 需使用https
    4. 每个小程序账号仅支持配置20个域名,每个域名最多绑定20个小程序,每个小程序一年内最多支持修改域名50次

    分享功能

    小程序直接分享的webview所在的页面,如果需要加上页面参数,那我们就需要处理一下了。

    1. webview内是不能直接发起分享的,需要先用wx.miniProgram.postMessage接口,把需要分享的信息,推送给小程序;推送给小程序的信息不是实时处理的,而是用户点击了分享按钮之后,小程序才回去读取的,这就要求每个需要分享的页面再进入的时候就发起wx.miniProgram.postMessage推送分享信息给小程序。
    2. 小程序页面通过bindmessage绑定的函数读取post信息,分享的信息会是一个列表,我们取最后一个分享就好,把分享信息处理好,存到data里面以便下一步onShareAppMessage调用。
    3. 用户点击分享时,会触发onShareAppMessage函数,在里面设置好对应的分享信息就好了。
    4. onload函数有一个option参数的,可以读取页面加载时url里带的参数,这时要对原先的onload函数进行改造,实现从option里读取链接信息。

    JavaScript

    // 网页wx.miniProgram.postMessage wx.miniProgram.postMessage({ data: { link: shareInfo.link, title: shareInfo.title, imgUrl: shareInfo.imgUrl, desc: shareInfo.desc } }) // 小程序index wxml设置 <web-view src="{{url}}" bindmessage="bindGetMsg"></web-view> // 小程序index js bindGetMsg: function (e) { if (!e.detail) { return } let list = e.detail.data if (!list || list.length === 0) { return } let info = list[list.length - 1] if (!info.link) { console.error('分享信息错误', list) return } let tokens = info.link.split('?') this.setData({ shareInfo: { title: info.title, imageUrl: info.imgUrl, path: `/page/index/index?urlData=${encodeURIComponent(tokens[1])}&urlToken=${tokens[0]}` } }) }, onShareAppMessage: function (res) { if (res.from === 'button') { // 来自页面内转发按钮 console.log(res.target) } let that = this return { title: that.data.shareInfo.title, path: that.data.shareInfo.path, imageUrl: that.data.shareInfo.imageUrl, success: function (res) { // 转发成功 }, fail: function (res) { // 转发失败 } } }, onLoad: function (option) { if (option.urlToken) { getApp().globalData.urlToken = option.urlToken } if (option.urlData) { getApp().globalData.urlData = option.urlData } this.setData({ url: getApp().globalData.urlToken + '?'

    • getApp().globalData.urlData }) },
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    // 网页wx.miniProgram.postMessage
    wx.miniProgram.postMessage({
      data: {
        link: shareInfo.link,
        title: shareInfo.title,
        imgUrl: shareInfo.imgUrl,
        desc: shareInfo.desc
      }
    })
    // 小程序index wxml设置
    <web-view src="{{url}}" bindmessage="bindGetMsg"></web-view>
    // 小程序index js
    bindGetMsg: function (e) {
        if (!e.detail) {
          return
        }
        let list = e.detail.data
        if (!list || list.length === 0) {
          return
        }
        let info = list[list.length - 1]
        if (!info.link) {
          console.error('分享信息错误', list)
          return
        }
        let tokens = info.link.split('?')
        this.setData({
          shareInfo: {
            title: info.title,
            imageUrl: info.imgUrl,
            path: `/page/index/index?urlData=${encodeURIComponent(tokens[1])}&urlToken=${tokens[0]}`
          }
        })
    },
    onShareAppMessage: function (res) {
        if (res.from === 'button') {
          // 来自页面内转发按钮
          console.log(res.target)
        }
        let that = this
        return {
          title: that.data.shareInfo.title,
          path: that.data.shareInfo.path,
          imageUrl: that.data.shareInfo.imageUrl,
          success: function (res) {
            // 转发成功
          },
          fail: function (res) {
            // 转发失败
          }
        }
    },
    onLoad: function (option) {
        if (option.urlToken) {
          getApp().globalData.urlToken = option.urlToken
        }
        if (option.urlData) {
          getApp().globalData.urlData = option.urlData
        }
        this.setData({
          url: getApp().globalData.urlToken + '?' +  getApp().globalData.urlData
        })
    },

    扫描普通二维码跳转特定页面

    除了分享功能之外,小程序还可以通过配置,实现扫描普通二维码跳转特定页面的功能。

    以下是微信对此功能的介绍

    为了方便小程序开发者更便捷地推广小程序,兼容线下已有的二维码,微信公众平台开放扫描普通链接二维码跳转小程序能力。

    功能介绍

    普通链接二维码,是指开发者使用工具对网页链接进行编码后生成的二维码。

    线下商户可不需更换线下二维码,在小程序后台完成配置后,即可在用户扫描普通链接二维码时打开小程序,使用小程序的功能。
    对于普通链接二维码,目前支持使用微信“扫一扫”或微信内长按识别二维码跳转小程序.

    二维码规则

    根据二维码跳转规则,开发者需要填写需要跳转小程序的二维码规则。要求如下:

    1. 二维码规则的域名须通过ICP备案的验证。
    2. 支持http、https、ftp开头的链接(如:、)。
    3. 一个小程序帐号可配置不多于10个二维码前缀规则。

    前缀占用规则

    开发者可选择是否占用符合二维码匹配规则的所有子规则。如选择占用,则其他帐号不可申请使用满足该前缀匹配规则的其他子规则。

    如:若开发者A配置二维码规则:,并选择“占用所有子规则“,其他开发者将不可以配置满足前缀匹配的子规则如。

    我推荐的方式

    webview实现方式

    1. 设置跳转功能小程序后台就可以设置,链接是分为四部分,路https://www.example.com/wxmin…。

      https://www.example.com 域名
      /wxmini/ 小程序前置规则,需要在服务器上建一个文件夹,并且把验证文件放在文件夹线
      home.html 需要跳转的网页页面
      a=1 跳转页面的参数
    2. 对onload函数再进行处理,实现普通二维码跳转。

    JavaScript

    // 对index onLoad在进行处理 onLoad: function (option) { this.resetOption(option) if (option.urlToken) { getApp().globalData.urlToken = option.urlToken } if (option.urlData) { getApp().globalData.urlData = option.urlData } this.setData({ url: getApp().globalData.urlToken + '?' + getApp().globalData.urlData }) }, resetOption: function (option) { if (!option) { return } if (option.q) { option.q = decodeURIComponent(option.q) if (option.q.indexOf('') == -1) { return } let tmp = option.q.replace('/wxmini', '') let tmps = tmp.split('?') option.urlToken = tmps[0] option.urlData = tmps[1] } else { option.urlData = decodeURIComponent(option.urlData) } }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    // 对index onLoad在进行处理
    onLoad: function (option) {
        this.resetOption(option)
        if (option.urlToken) {
          getApp().globalData.urlToken = option.urlToken
        }
        if (option.urlData) {
          getApp().globalData.urlData = option.urlData
        }
        this.setData({
          url: getApp().globalData.urlToken + '?' +  getApp().globalData.urlData
        })
    },
    resetOption: function (option) {
        if (!option) {
          return
        }
        if (option.q) {
          option.q = decodeURIComponent(option.q)
          if (option.q.indexOf('https://www.example.com/wxmini/') == -1) {
            return
          }
          let tmp = option.q.replace('/wxmini', '')
          let tmps = tmp.split('?')
          option.urlToken = tmps[0]
          option.urlData = tmps[1]
        } else {
          option.urlData = decodeURIComponent(option.urlData)
        }
    }
    <web-view src="https://www.itlao5.com"></web-view>
    

    本文由彩世界平台发布于新闻动态,转载请注明出处:微信小程序web-view

    关键词:

上一篇:CSS布局奇技淫巧:高度自适应

下一篇:没有了