H5页面调用微信扫一扫

19 篇文章 0 订阅
15 篇文章 0 订阅

需求: H5页面调用微信扫一扫扫描二维码,获取二维码内容
技术: vue,vuex
参考文档:微信开放文档
问题: Android正常打开扫一扫,ios必须刷新一下才能打开
解决:

  1. 在vue项目npm安装微信sdk

    npm install weixin-js-sdk
    

    安装完成之后在页面引入(在全局也行)

    import wx from "weixin-js-sdk";
    
  2. 点击扫一扫请求后台接口获取所需参数

    sys_click() {
    	let that = this;
    	$.ajax({
    		url: "请求地址",
    		type: "POST",
    		dataType: "JSON",
    		data: {
    			url:that.wxUrl,//这里的wxUrl是vuex里面的,接着往下看
    		},
    		success: res => {
    			that.resMsg = res;//这里我把拿到的参数赋值了一下,也可以直接用
    			wx.config({
    				// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    				debug: false,
    				// 必填,公众号的唯一标识
    				appId: that.resMsg.appId,
    				// 必填,生成签名的时间戳
    				timestamp: that.resMsg.timestamp,
    				// 必填,生成签名的随机串
    				nonceStr: that.resMsg.nonceStr,
    				// 必填,签名,见附录1
    				signature: that.resMsg.signature,
    				// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    				jsApiList: ["scanQRCode"]
    			});
    		}
    	});
    }
    
  3. 调用手机摄像头, 如果wx.config失败会wx.error,如果成功就wx.ready

    	wx.error(res => {
    		alert("出错了:" + res.errMsg);
    	});
    	wx.ready(() => {
    		wx.scanQRCode({
    			needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
    			scanType: ["qrCode"], // 可以指定扫二维码还是一维码,默认二者都有
    			success: res => {
    				alert("扫描成功", res.resultStr);
    				that.coding = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
    			}
    		});
    	});
    
  4. 如果这时候Android已经成功调起摄像头,而ios报invalid signature签名错误,那么就需要用到vuex

    报错原因:请求后台传入的页面地址(url参数)问题,如果Android和ios传一样的地址就会报错

    如果从 A 页面跳到 B(扫码) 页面,如果 A 页面地址123,B 页面地址是456,这个时候请求后台的url不可以都传123。因为ios会用 A 页面的地址去生成签名,而Android则会用 B 页面的地址去生成签名,所以传入后台的url参数必须是不一样的

    解决办法:在扫码的上一个页面判断手机机型,或者全局判断,如果是ios就把A页面的地址存入vuex里面的state变量里面(这里vuex里面的变量名我取的是wxUrl)。如果是Android,就在B页面把地址存入vuex,请求接口的时候就用vuex里面的变量

    判断是否是ios方法:

    let u = navigator.userAgent;
    let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
    

全部代码

A页面(从这个页面跳转到扫码页面)

<template>
	<div>
		<button @click="goCode">跳转扫码页面</button>
	</div>
</template>
<script>
import {mapMutations} from 'vuex';
export default {
	components: {
		mapMutations,
	},
	created() {
		this.isIOS();
  	},
  	methods: {
    	...mapMutations(['saveUrl','judgeModels']),
    	isIOS(){
		    // 判断手机机型,如果是ios就把本页面地址存到vuex
		    let u = navigator.userAgent;
		    let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
		    this.judgeModels(isiOS);
		    if(isiOS){
		      this.saveUrl(window.location.href)
		    }
		},
		goCode(){
			this.$router.push({
				name: "serve",
				params: {
				 id: 123456
				}
			});
		},
	}
};
</script>

B页面(扫码页面)

<template>
	<div>
		<input type="text" v-model="coding" placeholder="扫描二维码获取" />
		<button @click="sys_click">扫一扫</button>
	</div>
</template>
<script>
import wx from "weixin-js-sdk";
import {mapState, mapMutations} from 'vuex';
export default {
	components: {
		mapState,
		mapMutations,
	},
	computed:{
		...mapState(['model','wxUrl']),
	},
	data() {
		return {
			coding:'',
			resMsg: {}
		};
	},
	mounted() {
		if (!this.$route.params.id) {
      		this.$router.go(-1);
		      return;
    	}
		if(this.model=='android'){
			this.saveUrl(window.location.href)
		}
	},
	methods: {
		...mapMutations(['saveUrl']),
		// 扫一扫
		sys_click() {
			let that = this;
			$.ajax({
				url: "请求地址",
				type: "POST",
				dataType: "JSON",
				data: {
					url:that.wxUrl,
				},
				success: res => {
					that.resMsg = res;
					wx.config({
						// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
						debug: false,
						// 必填,公众号的唯一标识
						appId: that.resMsg.appId,
						// 必填,生成签名的时间戳
						timestamp: that.resMsg.timestamp,
						// 必填,生成签名的随机串
						nonceStr: that.resMsg.nonceStr,
						// 必填,签名,见附录1
						signature: that.resMsg.signature,
						// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
						jsApiList: ["scanQRCode"]
					});
				}
			});
			wx.error(res => {
				alert("出错了:" + res.errMsg);
			});
			wx.ready(() => {
				wx.scanQRCode({
					needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
					scanType: ["qrCode"], // 可以指定扫二维码还是一维码,默认二者都有
					success: res => {
						alert("扫描成功", res.resultStr);
						that.coding = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
					}
				});
			});
		},
	},
};
</script>

vuex页面

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    wxUrl: '',
    model:''
  },
  mutations: {
    // 更改页面地址
    saveUrl(state, value) {
      state.wxUrl = value;
    },
    // 判断手机类型
    judgeModels(state, value){
      if(value){
        state.model = 'ios';
      }else{
        state.model = 'android'
      }
    }
  },
})
  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值