微信H5拉起(跳转)微信小程序

12 篇文章 0 订阅
11 篇文章 0 订阅
  • main.js配置忽略wx-open-launch-weapp
Vue.config.ignoredElements = ['wx-open-launch-weapp'];
  • template
<template>
	<view class="index-wrapper">
		<!-- 这里必须要设置宽高,否则渲染出来没有宽高 wx-open-launch-weapp-->
		<view class="wrapper">
			<view class="">点击下面按钮跳转</view>
			<wx-open-launch-weapp
				id="launch-btn"
				class="wx-weapp-wrapper"
				:username="zzh.appId"
				:path="zzh.path"
				@launch="handleLaunch"
				@error="handleError"
			>
				<script type="text/wxtag-template">
					<button class="btn">销售云(不会被显示出来)</button>
				</script>
				<view class="btn">销售云</view>
			</wx-open-launch-weapp>
		</view>
	</view>
</template>
  • script
<script>
	import wechat from '@/utils/wechat';
	export default {
		created() {
			const oScript = document.createElement('script');
			oScript.type = 'text/javascript';
			//需要注意的是,我把jweixin-1.6.0.js下载到本地引用,总是报错
			//换成引用远程的方式就可以,一定要注意
			oScript.src = 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js';
			oScript.onload = this.wxmini
			document.body.appendChild(oScript);
		},
		methods: {
			wxmini(){
				const _this = this;
				if (!_this.$mWechat.isWechat()) {
					_this.$mHelper.toast('请在微信客户端打开');
					return;
				}
				const hrefURL = window.location.href;
				const signURL = encodeURIComponent(hrefURL.indexOf("#") > -1 ? hrefURL.split('#')[0] : hrefURL);
				wechat.getH5Sign(signURL).then(data => {
					wx.config({
						debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
						...data,
						jsApiList: ['onMenuShareTimeline'], // 必填,需要使用的JS接口列表
						openTagList: ['wx-open-launch-weapp'] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
					});
					wx.ready(function () {
						console.log('ready')
					});
				});
			},
			//监听跳转
			handleLaunch() {
				console.log('跳转');
				this.$mHelper.toast('小程序跳转成功handleLaunch');
			},
			//监听错误
			handleError() {
				console.log('失败');
				this.$mHelper.toast('小程序跳转失败');
			}
		}
	}
</script>
  • style
<style lang="scss">
	.wrapper {
		position: absolute;
		width: 100%;
		height: 100px;
		top: 0;
		left: 0;
		opacty: 0;
		text-align: center;
		margin-top: 50px;
		.wx-weapp-wrapper {
			display: block;
			text-align: center;
			font-size: 16px;
			border: 1px solid #d8d8d8;
			border-radius: 20px;
			margin: 0 50px;
			box-shadow: 2px 2px 4px 2px #d8d8d8;
			padding: 10px;
		}
	}
</style>
  • 结果
    如果开发者工具弹出下面提示,就可以把代码打包到服务器上测试了(微信开发者工具是不会又真正效果展示的)
    在这里插入图片描述
  • 后端处理签名等数据
public ResponseResult getAccessToken() {
	String accessTokenStr = redisHelper.getStr("mpshop-h5-access_token_expires_in");
	if (StringUtils.isNotEmpty(accessTokenStr)) {
	    logger.info("access_token已缓存:" + accessTokenStr);
	    return new ResponseResult(ResponseResult.SUCCESS, "成功", accessTokenStr);
	}
	
	//如果缓存中没有就去微信官方获取
	String[] apps = new String[]{"wechatH5AppId", "wechatH5AppSecret"};
	List<MpshopConfig> configs = configMapper.getByCodes(apps);
	final String[] appId = {h5AppId};
	final String[] appSecret = {h5AppSecret};
	if (!CollectionUtils.isEmpty(configs)) {
	    configs.stream().forEach(item -> {
	        if ("wechatH5AppId".equals(item.getCode())) {
	            appId[0] = item.getValue();
	        }
	        if ("wechatH5AppSecret".equals(item.getCode())) {
	            appSecret[0] = item.getValue();
	        }
	    });
	}
	
	String url = h5AccessTokenUrl.replace("APPID", appId[0]).replace("APPSECRET", appSecret[0]);
	String result = HttpRequest.get(url).timeout(6000).execute().body();
	logger.info("获取accessToken的返回:" + result);
	if (StringUtils.isEmpty(result)) {
	    return new ResponseResult(ResponseResult.ERROR_400,"获取accessToken失败");
	}
	
	JSONObject data = JSON.parseObject(result);
	if (data.containsKey("access_token")) {
	    //说明返回成功
	    if (data.containsKey("expires_in")) {
	        //微信官方的默认过期时间应该是7200秒,我们这里设置一定要小于7200秒,但是不能太小,请求太频繁,会被微信拦截掉
	        redisHelper.setStr("mpshop-h5-access_token_expires_in", data.getString("access_token"), 3600, TimeUnit.SECONDS);
	    }
	    return new ResponseResult(ResponseResult.SUCCESS, "成功", data.getString("access_token"));
	}
	
	if (data.containsKey("errcode")) {
	    return new ResponseResult(ResponseResult.ERROR_400, data.getString("errmsg"));
	}
	
	return new ResponseResult(ResponseResult.ERROR_400, "获取accessToken失败");
}

public ResponseResult getJsApiTicket() {
    String jsApiTicketStr = redisHelper.getStr("mpshop-h5-jsapi_ticket_expires_in");
    if (StringUtils.isNotEmpty(jsApiTicketStr)) {
        logger.info("jsapi_ticket已缓存:" + jsApiTicketStr);
        return new ResponseResult(ResponseResult.SUCCESS, "成功", jsApiTicketStr);
    }

    ResponseResult responseResult = this.getAccessToken();
    if (ResponseResult.SUCCESS != responseResult.getCode() || null == responseResult.getData()) {
        return responseResult;
    }

    String accessToken = String.valueOf(responseResult.getData());
    String url = h5JsApiTicketUrl.replace("ACCESS_TOKEN", accessToken);
    String result = HttpRequest.get(url).timeout(6000).execute().body();
    logger.info("获取jsApiTicket的返回:" + result);
    if (StringUtils.isEmpty(result)) {
        return new ResponseResult(ResponseResult.ERROR_400,"获取TICKET失败");
    }

    JSONObject data = JSON.parseObject(result);
    if (0 != data.getIntValue("errcode") && !data.containsKey("ticket")) {
        return new ResponseResult(ResponseResult.ERROR_400,"获取TICKET失败");
    }

    //说明返回成功
    if (data.containsKey("expires_in")) {
        //微信官方的默认过期时间应该是7200秒,我们这里设置一定要小于7200秒,但是不能太小,请求太频繁,会被微信拦截掉
        redisHelper.setStr("mpshop-h5-jsapi_ticket_expires_in", data.getString("ticket"), 3600, TimeUnit.SECONDS);
    }

    return new ResponseResult(ResponseResult.SUCCESS,"成功", data.getString("ticket"));
}

public ResponseResult getH5Signature(String hrefURL) {
    ResponseResult responseResult = this.getJsApiTicket();
    if (ResponseResult.SUCCESS != responseResult.getCode() || null == responseResult.getData()) {
        return responseResult;
    }

    String jsApiTicket = String.valueOf(responseResult.getData());
    String nonceStr = StringUtil.getRandom(10);
    //需要注意的是,这里的时间戳是秒级时间戳(10位),不是毫秒级(13位)
    String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳

    try {
        String url = URLDecoder.decode(hrefURL, "UTF-8");
        //String signature = SignUtil.createSignature(jsApiTicket, nonceStr, timestamp, signURL);
        String signature = DigestUtil.sha1Hex("jsapi_ticket=" + jsApiTicket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url);
        logger.info("获取到的signature:" + signature);
        if (StringUtils.isEmpty(signature)) {
            return new ResponseResult(ResponseResult.ERROR_400,"获取签名失败");
        }

        Map<String, Object> data = new HashMap<>(4);
        data.put("appId", h5AppId);
        data.put("nonceStr", nonceStr);
        data.put("timestamp", timestamp);
        data.put("signature", signature);

        logger.info("data数据:" + JSONUtil.toJsonStr(data));
        return new ResponseResult(ResponseResult.SUCCESS,"成功", data);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return new ResponseResult(ResponseResult.ERROR_400,"未知错误");
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值