需求: H5頁面呼叫微信掃一掃掃描二維碼,獲取二維碼內容
技術: vue,vuex
參考檔案:微信開放檔案
踩坑: Android正常打開掃一掃,ios必須重繪一下才能打開(最后有解決辦法)
步驟:
-
在vue專案npm安裝微信sdk
npm install weixin-js-sdk安裝完成之后在頁面引入(在全域也行)
import wx from "weixin-js-sdk"; -
點擊掃一掃請求后臺介面獲取所需引數
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"] }); } }); } -
呼叫手機攝像頭, 如果
wx.config失敗會wx.error,如果成功就wx.readywx.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傳一樣的地址就會報錯,舉個例子說明一下
假如掃碼頁面是B頁面,頁面地址是123,B頁面是從A頁面跳過來的,而A頁面的地址是456,這個時候你如果url引數都傳123就不行,因為ios會用A頁面的地址去生成簽名,而Android則會用B頁面的地址去生成簽名,所以傳入后臺的url引數必須是不一樣的解決辦法:在掃碼的上一個頁面判斷手機機型,或者全域判斷,如果是ios就把當前頁面的地址存入vuex里面的state變數里面(這里vuex里面的變數名我取的是wxUrl),如果是Android,就在掃碼頁面把地址存入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'
}
}
},
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/293756.html
標籤:其他
