h5打开微信小程序+微信扫一扫打开小程序

接到需求 先调查

1.链接打开小程序

百度有1种方法思路是:前端写个h5页面,拿到链接里的参数 用该参数传给服务端 服务端调用微信urlscheme接口 生成打开小程序的短链接 返给前端 h5通过location.href去跳转此短链接即可

前端h5页面代码如下:





经过上述方法测试 该方法只适用于 短信 除微信外的浏览器 如下官网介绍

image.png

而需求是:在微信聊天内打开小程序 所以需要支持微信浏览器,查资料发现上述方法自动废弃

于是又搜到方法2:使用微信外部标签wx-open-launch-weapp

标签介绍如下:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html#21
即写个h5页面 放入此标签 通过配置此标签的属性 包括path等 点击此标签时打开小程序指定的页面
查资料得 此标签只支持打开以下两种情形的小程序:

image.png

因为我的小程序是独立申请的 没有依赖公众号,因此,只能选择方法2 将h5页面静态网站托管在小程序云托管下面
方法和h5项目源码如下:
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/staticstorage/jump-miniprogram.html
将源码下载下来 查找需要替换的参数替换成自己小程序的参数即可
下一步就是将这个h5项目托管起来(是需要按流量收费的,一开始免费使用一个月 不怎么贵)
步骤:在微信开发者工具中点云开发--->更多--->静态网站-->上传文件夹 选择刚刚的h5项目 再在当前页面的网站配置里 填写索引文件路径h5-open-miniprogram/h5/jump-mp.html
以上完成链接分享打开小程序
具体在小程序中需要接收参数可以在h5页面标签配置的path中传递
我是在js中配好path值 通过标签属性赋值给的path

 var fid = getQueryStringAll('fromType');
 var transportBulkLineId = getQueryStringAll('transportBulkLineId');
 var launchBtn = document.getElementById('launch-btn')
 var path = '/pages/index/index.html?fromType=' + fid + '&transportBulkLineId=' + transportBulkLineId + '&isLinkUrlCome=1';
 launchBtn.setAttribute('path', path)

小程序中接收参数:

  if ((JSON.stringify(options) != '{}' && options.isLinkUrlCome)) {
      let _param = {
          transportLineId: options.transportBulkLineId || '',
          fid: options.fromType || ''
      }
      this.setData({
        param: _param
      })
    }

注意:以上方法只支持发布过后的小程序代码--即打开的小程序是发布版本后的小程序

补充方法 绑定公众号 链接打开小程序

其实并不一定是将小程序绑定在微信公众号下 而是已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签跳转任意合法合规的小程序
也就是只要找一个认证过的公众号 在公众号的 功能设置 界面中点击“JS接口安全域名”后面对应的“设置”按钮。把h5页面的域名配置上去即可
vue写法





注意:
1.需要在index.html中引用https//res.wx.qq.com/open/js/jweixin-1.6.0.js
1.6.0版本
2.写个wxjssdk的js 调用后端接口配置wx.config

/* eslint-disable */
import Vue from 'vue'
import { getWxSignature } from '@/api/commonApi'

let JssdkObj = {
    is_load_wxjssdk: false,
    is_share_flag: false,
    is_get_loc: false,
    is_hide_wxmenu: false,
    wx_share_param: {
        title: '', //分享自定义标题,不传就按照
        stime_title: '', //分享朋友圈标识,不传就使用title
        desc: '', //分享自定义内容,限制30个字
        img_url: '', //分享自定义图片
        timestamp: '',
        nonceStr: '',
        share_uid: '-1', //分享人加密用户id
        state: '', //分享模块标识
        app_id: '',
        share_url: '',
        self_params: '', //自定义参数值
        successFunc() {},
        cancleFunc() {},
        failFunc() {},
        commFunc() {}
    },
    wx_auth_json: null,
    wx_jsapi_list: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'updateAppMessageShareData', 'updateTimelineShareData', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getLocalImgData', 'getNetworkType', 'openLocation', 'getLocation', 'closeWindow', 'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'scanQRCode', 'chooseWXPay', 'hideOptionMenu'],
    wx_hide_menu_list: ['menuItem:share:appMessage', 'menuItem:share:timeline', 'menuItem:share:qq', 'menuItem:share:weiboApp', 'menuItem:favorite', 'menuItem:share:facebook', 'menuItem:share:QZone', 'menuItem:copyUrl', 'menuItem:openWithQQBrowser', 'menuItem:openWithSafari', 'menuItem:share:email'],
    wx_show_menu_list: ['menuItem:share:appMessage', 'menuItem:share:timeline'],
    wx_open_tag_list: ['wx-open-launch-weapp'],
    isWeixin() {
        return navigator.userAgent.toLowerCase().indexOf('micromessenger') > -1
    },
    isDevEnv() {
        return process.env.VUE_APP_ENV === 'development'
    }
}

export default {
    init() {
        if (JssdkObj.isWeixin()) {
            if (JssdkObj.is_load_wxjssdk) {
                return false
            }
            var myScript = document.createElement('script')
            myScript.src = '//res2.wx.qq.com/open/js/jweixin-1.6.0.js'
            document.body.appendChild(myScript)
            Vue.nextTick(() => {
                JssdkObj.is_load_wxjssdk = true
            })
        }
    },
    initHideSharePage() {
        let _this = this
        JssdkObj.is_hide_wxmenu = false
        if (JssdkObj.isWeixin()) {
            console.log('====initHideSharePage===window.WeixinJSBridge=' + typeof window.WeixinJSBridge)
            if (typeof window.WeixinJSBridge !== 'undefined') {
                // window.WeixinJSBridge同一页面只能调用一次,所以使用wx接口处理下
                window.WeixinJSBridge.call('hideOptionMenu')
                if (typeof wx !== 'undefined') {
                    wx.hideMenuItems({
                        menuList: ['menuItem:share:appMessage', 'menuItem:share:appMessage', 'menuItem:share:timeline'] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮,所有menu项见附录3
                    })
                }
                JssdkObj.is_hide_wxmenu = true
                return false
            }
            setTimeout(() => {
                _this.initHideSharePage()
            }, 200)
        }
    },
    // 展示微信分享效果
    initSharePage(json) {
        try {
            this.setShareParam(json)
            this.getWxAuthIfs()
        } catch (error) {
            console.log('初始化分享内容失败,原因:', error)
            this.initHideSharePage()
        }
    },
    initWxJsSdk(json, isNeedWxAuth) {
        /**
         * json={
         *  is_wx_share:0/1 // 1打开,0关闭 字符串类型,不然默认为0
         *  is_wx_loc:0/1 // 1打开,0关闭 字符串类型,不然默认为0
         *  wxLocCallback(){} // 当is_wx_loc定位标识打开,微信定位成功会回调该函数
         * }
         */
        let _isNeedWxAuth = isNeedWxAuth || true
        JssdkObj.is_share_flag = false
        try {
            if (json.is_wx_share === '1') {
                this.setShareParam(json)
            }
            if (json.is_wx_loc === '1') {
                JssdkObj.is_get_loc = true
                JssdkObj.wxLocCallback = typeof json.wxLocCallback === 'function' ? json.wxLocCallback : () => {}
            }
            if (_isNeedWxAuth) {
                this.getWxAuthIfs()
            }
        } catch (error) {
            console.log('=====initSharePage', JOSN.stringify(error))
        }
    },
    setShareParam(json) {
        /**
         * json={
         *  state,分享模块标识
         *  share_uid,分享卡加用户ID
         *  title,分享标题,不传则以服务器配置
         *  stime_title,朋友圈分享标题内容,为空则直接使用title
         *  desc,分享内容,不传则以服务器配置
         *  img_url,分享图片,不传则以服务器配置
         *  self_params, 自定义参数值(不能带参数名称)
         *  success_func({share_type:'friend/time_line'}){},分享成功回调函数,friend-好友分享标识,time_line-朋友圈分享标识
         *  cancle_func({share_type:'friend/time_line'}){},取消分享动作回调函数,friend-好友分享标识,time_line-朋友圈分享标识
         *  fail_func({share_type:'friend/time_line'}){},分享失败回调函数,friend-好友分享标识,time_line-朋友圈分享标识
         *  comm_func({share_type:'friend/time_line'}){}分享公共(成功/失败都会调用)回调函数,friend-好友分享标识,time_line-朋友圈分享标识
         * }
         */
        JssdkObj.is_share_flag = true
        JssdkObj.wx_share_param.state = json.state || ''
        JssdkObj.wx_share_param.title = json.title || '缺少分享内容'
        JssdkObj.wx_share_param.stime_title = json.stime_title || JssdkObj.wx_share_param.title
        JssdkObj.wx_share_param.desc = json.desc || '缺少分享内容'
        JssdkObj.wx_share_param.img_url = json.img_url || ''
        JssdkObj.wx_share_param.self_params = json.self_params || ''
        JssdkObj.wx_share_param.share_uid = json.share_uid || '-1'
        JssdkObj.wx_share_param.successFunc = typeof json.success_func === 'function' ? json.success_func : () => {}
        JssdkObj.wx_share_param.cancleFunc = typeof json.cancle_func === 'function' ? json.cancle_func : () => {}
        JssdkObj.wx_share_param.failfunc = typeof json.fail_func === 'function' ? json.fail_func : () => {}
        JssdkObj.wx_share_param.commFunc = typeof json.comm_func === 'function' ? json.comm_func : () => {}
    },
    getWxAuthIfs() {
        let _this = this
        let link = window.location.href
        link = window.location.href.split('#')[0]
        Vue.prototype.$toast.loading({
            message: '加载中'
        })
        getWxSignature({
            url: encodeURIComponent(link)
        }).then(response => {
            console.log('微信签名getWxSignature', response)
            if (response.data.reCode === '0') {
                let resJson = response.data.result
                setTimeout(function() {
                    _this.regWxConfigIfs(resJson)
                }, 200)
            } else if (JssdkObj.wx_auth_json !== null) {
                _this.regWxConfigIfs(JssdkObj.wx_auth_json)
            }
        }).catch(function(error) {
            console.log('=getWxAuthIfs=catch===调用失败,' + JSON.stringify(error))
            if (JssdkObj.wx_auth_json !== null) {
                _this.regWxConfigIfs(JssdkObj.wx_auth_json)
            }
        })
    },
    regWxConfigIfs(json) {
        var _this = this
        JssdkObj.wx_auth_json = json
        if (typeof window.WeixinJSBridge === 'undefined' || typeof wx === 'undefined') {
            setTimeout(function() {
                _this.regWxConfigIfs(json)
            }, 200)
            return false
        }
        wx.config({
            debug: JssdkObj.isDevEnv(), // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: json.appId, // 必填,公众号的唯一标识
            timestamp: Number(json.timeStamp), // 必填,生成签名的时间戳
            nonceStr: json.nonceStr, // 必填,生成签名的随机串
            signature: json.signature, // 必填,签名
            jsApiList: JssdkObj.wx_jsapi_list, // 必填,需要使用的JS接口列表
            openTagList: JssdkObj.wx_open_tag_list
        })
        this.onWxReady()
    },
    onWxReady() {
        var _this = this
        try {
            wx.ready(function(res) {
                    // config信息验证后会执行ready方法,
                    // 所有接口调用都必须在config接口获得结果之后,
                    // config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,
                    // 则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,
                    // 则可以直接调用,不需要放在ready函数中。
                    console.log('wx.ready', res)
                    _this.checkAllJsApi()
                    _this.openShareConfig()
                    if (JssdkObj.is_get_loc) {
                        _this.getWxLocation()
                    }
                })
                // 验证失败
            wx.error(function(res) { // 如果失败,就隐藏右上角的所有菜单
                console.log('wx.error=', res)
                _this.initHideSharePage()
            })
        } catch (err) {
            _this.initHideSharePage()
        }
    },
    onShowMenuItems() {
        var _this = this
        console.log('执行了onShowMenuItems')
        if (typeof window.WeixinJSBridge === 'undefined' || JssdkObj.wx_share_param.app_id.length === 0) {
            setTimeout(function() {
                _this.onShowMenuItems()
            }, 200)
        } else {
            console.log(
                '====onShowMenuItems:' + JSON.stringify(JssdkObj.wx_show_menu_list)
            )
            wx.showMenuItems({
                menuList: JssdkObj.wx_show_menu_list // 要显示的菜单项,所有menu项见附录3
            })
        }
    },
    checkAllJsApi() {
        try {
            wx.checkJsApi({
                jsApiList: JssdkObj.wx_jsapi_list, // 需要检测的JS接口列表,所有JS接口列表见附录2,
                success: function(res) {
                    // 以键值对的形式返回,可用的api值true,不可用为false
                    // 如:{'checkResult':{'chooseImage':true},'errMsg':'checkJsApi:ok'}
                    let resStr = JSON.stringify(res)
                    if (resStr.indexOf(':false') > -1) {
                        console.log('checkJsApi:' + resStr)
                    }
                }
            })
        } catch (err) {
            console.log('checkJsApi调用失败,原因:' + JSON.stringify(err))
        }
    },
    updateAppMessageShareData() {
        try {
            //自定义“分享给朋友”的分享内容,需在用户可能点击分享按钮前就先调用
            wx.updateAppMessageShareData({
                title: JssdkObj.wx_share_param.title, // 分享标题
                desc: JssdkObj.wx_share_param.desc, // 分享描述
                link: JssdkObj.wx_share_param.share_url.replace('{WX_SHARE_TYPE}', '1'), // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                imgUrl: JssdkObj.wx_share_param.img_url, // 分享图标
                success: function(res) {
                    console.log('分享到好友成功:' + JSON.stringify(res))
                    JssdkObj.wx_share_param.successFunc({ share_type: 'friend' })
                    JssdkObj.wx_share_param.commFunc({ share_type: 'friend' })
                },
                trigger: function() {
                    console.log('用户点击分享到好友')
                },
                fail: function(res) {
                    console.log('分享到好友失败' + JSON.stringify(res))
                }
            })
        } catch (err) {
            console.log(
                'updateAppMessageShareData调用失败,原因:' + JSON.stringify(err)
            )
        }
    },
    updateTimelineShareData() {
        try {
            //自定义“分享到朋友圈”按钮的分享内容,需在用户可能点击分享按钮前就先调用
            wx.updateTimelineShareData({
                title: JssdkObj.wx_share_param.stime_title, // 分享标题
                link: JssdkObj.wx_share_param.share_url.replace('{WX_SHARE_TYPE}', '0'), // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                imgUrl: JssdkObj.wx_share_param.img_url, // 分享图标
                success: function(res) {
                    console.log('分享到朋友圈成功:' + JSON.stringify(res))
                    JssdkObj.wx_share_param.successFunc({ share_type: 'time_line' })
                    JssdkObj.wx_share_param.commFunc({ share_type: 'time_line' })
                },
                trigger: function() {
                    console.log('用户点击分享到朋友圈')
                },
                fail: function(res) {
                    console.log('分享到朋友圈失败' + JSON.stringify(res))
                }
            })
        } catch (err) {
            console.log(
                'updateTimelineShareData调用失败,原因:' + JSON.stringify(err)
            )
        }
    },
    onMenuShareAppMessage() {
        wx.onMenuShareAppMessage({
            title: JssdkObj.wx_share_param.title,
            desc: JssdkObj.wx_share_param.desc,
            link: JssdkObj.wx_share_param.share_url.replace('{WX_SHARE_TYPE}', '1'),
            imgUrl: JssdkObj.wx_share_param.img_url,
            trigger: function(res) {
                // console.log('用户点击分享到好友')
            },
            success: function(res) {
                console.log('old分享好友成功:' + JSON.stringify(res))
                JssdkObj.wx_share_param.successFunc({ share_type: 'friend' })
                JssdkObj.wx_share_param.commFunc({ share_type: 'friend' })
            },
            cancel: function(res) {
                //  console.log('分享到好友操作已被取消')
                JssdkObj.wx_share_param.cancelFunc({ share_type: 'friend' })
            },
            fail: function(res) {
                // console.log('分享到好友失败')
                // console.log(JSON.stringify(res))
                JssdkObj.wx_share_param.failFunc({ share_type: 'friend' })
                JssdkObj.wx_share_param.commFunc({ share_type: 'friend' })
            }
        })
    },
    onMenuShareTimeline() {
        wx.onMenuShareTimeline({
            title: JssdkObj.wx_share_param.stime_title,
            link: JssdkObj.wx_share_param.share_url.replace('{WX_SHARE_TYPE}', '0'),
            imgUrl: JssdkObj.wx_share_param.img_url,
            trigger: function(res) {
                console.log('用户点击分享到朋友圈', res)
            },
            success: function(res) {
                console.log('old分享到朋友圈成功:' + JSON.stringify(res))
                JssdkObj.wx_share_param.successFunc({ share_type: 'time_line' })
                JssdkObj.wx_share_param.commFunc({ share_type: 'time_line' })
            },
            cancel: function(res) {
                console.log('分享到朋友圈操作已被取消', res)
                JssdkObj.wx_share_param.cancelFunc({ share_type: 'time_line' })
            },
            fail: function(res) {
                console.log('分享到朋友圈失败', res)
                JssdkObj.wx_share_param.failFunc({ share_type: 'time_line' })
                JssdkObj.wx_share_param.commFunc({ share_type: 'time_line' })
            }
        })
    },
    getWxLocation() {
        try {
            wx.getLocation({
                type: 'gcj02',
                success: function(res) {
                    var latitude = res.latitude
                    var longitude = res.longitude
                    if (typeof JssdkObj.wxLocCallback === 'function') {
                        JssdkObj.wxLocCallback({
                            result: { reCode: '200', reInfo: '微信定位成功' },
                            latitude,
                            longitude
                        })
                    }
                    JssdkObj.wxLocCallback = null
                },
                fail: function(res) {
                    console.log('获取经纬度失败,原因:' + JSON.stringify(res))
                    if (typeof JssdkObj.wxLocCallback === 'function') {
                        JssdkObj.wxLocCallback({
                            result: { reCode: '1', reInfo: '获取经纬度失败' }
                        })
                    }
                    JssdkObj.wxLocCallback = null
                }
            })
        } catch (err) {
            console.log('getWxLocation调用失败,原因:' + JSON.stringify(err))
        }
    },
    closeShareConfig() {
        // 隐藏菜单
        if (typeof wx !== 'undefined') {
            wx.hideAllNonBaseMenuItem()
        }
    },
    openShareConfig(json) {
        if (!JssdkObj.is_share_flag) {
            console.log('//分享开关未打开')
            return false
        }
        if (!JssdkObj.is_hide_wxmenu) {
            let _this = this
            setTimeout(() => {
                _this.openShareConfig(json)
            }, 200)
            return false
        }
        if (typeof json === 'object') {
            this.setShareParam(json)
        }
        // 防止菜单没有隐藏
        if (typeof wx !== 'undefined') {
            wx.hideAllNonBaseMenuItem()
        }
        this.onShowMenuItems()
        this.onMenuShareAppMessage()
        this.onMenuShareTimeline()
    },
    openWxLocation(lat, lng, address) {
        wx.openLocation({
            latitude: parseFloat(lat), // 纬度,浮点数,范围为90 ~ -90
            longitude: parseFloat(lng), // 经度,浮点数,范围为180 ~ -180。
            name: '[商家位置]', // 位置名
            address: address, // 地址详情说明
            scale: 15 // 地图缩放级别,整形值,范围从1~28。默认为最大
                // infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转
        })
    },
    showImg(imgUrl, currUrl) {
        wx.previewImage({
            current: currUrl, // 当前显示图片的http链接
            urls: imgUrl // 需要预览的图片http链接列表
        })
    },
    chooseImage() {
        this.getWxAuthIfs()
        var _this = this
        wx.chooseImage({
            count: 6, // 默认9
            sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
            sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
            success: function(res) {
                var localIds = res.localIds // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
                console.log('微信图片返回', localIds)
                _this.uploadImage(localIds[0])
            },
            fail: function(err) {
                console.log(JSON.stringify(err))
            }
        })
    },
    uploadImage(id) {
        wx.uploadImage({
            localId: id, // 需要上传的图片的本地ID,由chooseImage接口获得
            isShowProgressTips: 1, // 默认为1,显示进度提示
            success: function(res) {
                const serverId = res.serverId // 返回图片的服务器端ID
                console.log('serverId', serverId)
            }
        })
    },
    showShareWxGuide(shareMsg) {
        const _shareMsg = shareMsg || '点击右上角可转发分享哦~'
        Vue.$toast({ message: _shareMsg, position: 'middle', duration: 3000 })
    }
}

以上是微信sdk常用功能包括上传图片 获取地址 分享等一系列的配置都写上了

在main.js中 引用上述js 并调用

import ShareMethods from './assets/js/wxJssdk'
Vue.config.ignoredElements = ['wx-open-launch-weapp']
Vue.use(ShareMethods)
Vue.prototype.$shareJs = ShareMethods
ShareMethods.init() // 微信分享初始化

2.扫一扫打开小程序

小程序开发管理中提供了扫一扫打开小程序的开关 这里先去开启 并配置规则
方法如下:
小程序开放平台 开发管理--开发设置--- 扫普通链接二维码打开小程序

配个h5页面(中转页)路径 通过这个路径的码可以打开小程序(其实这个h5没什么功能作用 只是在小程序平台配置个与小程序页面的一个映射)
配置完成后即可打开小程序
在小程序中取二维码中路径的参数

onLoad(options) {
    if (options && options.q) {
      // 扫码进来的
      let url= decodeURIComponent(options.q);
      this.setData({
        localUrl: url
      })
      this.isScanComeFun();
    }
isScanComeFun() {
    // start扫二维码进来的
    try {
      let url = this.data.localUrl;
      console.log('当前页url', url);
      var _obj = {
        transportLineId: util.getQueryVariable('transportBulkLineId',url) || '',
        fid: util.getQueryVariable('fromType',url) || ''
      }
      console.log('参数', _obj);
    } catch (error) {
    }
  }

注意:配置体验版的小程序 扫一扫最多只支持配置5个url即参数不可变 变了就算一个url
线上直接配h5域名即可 参数可以变

你可能感兴趣的:(h5打开微信小程序+微信扫一扫打开小程序)