這是我第一次公眾號開發,本以為看著微信官方文件直接複製貼上就好了,沒想到是我天真了,爬過一個坑又入一個坑!就這麼一個簡單的事,竟然搞了一下午,所以寫了這篇文章,希望可以幫到大家!
第一步:引入 weixin-js-sdk
- 方式1:靜態 html 引入
直接在 html 檔案內,使用 script 引入:
<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
- 方式二:vue 單頁面
// 可以在主入口檔案 index.html 內引入 <script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script> // 使用頁面通過 window.wx 方式訪問 wx 模組
或者
// 安裝 npm install weixin-js-sdk //引入 import wx from 'weixin-js-sdk'
第二步:許可權驗證配置
wx.config({ debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。 appId: 'xxxx', // 必填,公眾號的唯一標識 timestamp: 'xx', // 必填,生成簽名的時間戳 nonceStr: 'xx', // 必填,生成簽名的隨機串 signature: 'xx',// 必填,簽名 jsApiList: ['scanQRCode'] // 必填,需要使用的JS介面列表 });
timestamp,nonceStr,signature 重要資訊請根據自己的公眾號資訊去獲取。需要注意的是 debug 除錯的時候,設定為 true ,會自動彈出配置成功或失敗資訊,除錯時可以藉助它。
第三步:呼叫掃一掃介面
我們在需要的按鈕處,點選事件處開始呼叫掃碼介面,如:
scaneMethod() { var ua = navigator.userAgent.toLowerCase() var isWeixin = ua.indexOf('micromessenger') !== -1 if (!isWeixin) { alert('請用微信開啟連線,才可使用掃一掃') } window.wx.scanQRCode({ needResult: 1, // 預設為0,掃描結果由微信處理,1則直接返回掃描結果, scanType: ['qrCode', 'barCode'], // 可以指定掃二維碼還是一維碼,預設二者都有 success: function (res) { // 掃碼成功,跳轉到二維碼指定頁面(res.resultStr為掃碼返回的結果) // location.href = res.resultStr; var scan = res.resultStr alert(scan) } }, error: function (res) { if (res.errMsg.indexOf('function_not_exist') > 0) { alert('當前版本過低,請進行升級') } }, }) }
做了一個判斷處理,檢查只有微信瀏覽器,其他瀏覽器不可以呼叫:
var isWeixin = ua.indexOf('micromessenger') !== -1 if (!isWeixin) { alert('請用微信開啟連線,才可使用掃一掃') }
第四步:真機測試
先宣告一下,我的專案是 vue 單頁面。
真機測試的時候,一直在提示:
errMsg:config:invalid signature
中文叫做簽名無效。
查詢原因是因為我的簽名獲取來和官方 微信 js 介面簽名校驗工具獲取來的資料不一樣,很明顯獲取的簽名有問題,是因為我的 url 配置和前端調起介面的 url 不一致造成的。
第五步:蘋果手機測試
蘋果手機真機測試,提示錯誤資訊為:
the permission value is offline verifying
翻譯為中文:許可權值正在離線驗證
這個錯誤原因是 config 沒有正確執行。
又繼續去檢查簽名的問題,最後發現是後臺介面欄位寫錯了,欲哭無淚,總之還是簽名資訊錯誤。
第六步:安卓正常,蘋果點選無反應
用安卓測試的時候,竟然好了,完美展示掃碼結果,以為要好了。使用 ios 測試的時候,竟然發現點選的時候沒有任何反應。
找了半天原因,是因為 window.location.href 不同造成的。
alert(window.location.href)
測試結果:
安卓:https://hp.******.net/
IOS:https://hp.******.net//
IOS 手機就是因為 url 與簽名配置處的 url 不同,所以導致 config 執行失敗。究其原因是因為我的 vue-router 是 hash 模式。
解決方案:把我的 hash 模式換成 history 模式。記得後臺也需要配置 nginx 。
第七步:IOS 掃碼無反應
當 IOS 能調起介面的那一刻,我以為要成功了,哪知道它就是要與 安卓 與眾不同,掃碼之後沒有任何反應,但是如果你快速地連續多掃幾次就會出現結果。
你就說要命不?網上查詢了半天,看見有的人說有延時,最後想幹脆加個延時算了。
let isAndriod = ua.indexOf('andriod') !== -1 window.wx.scanQRCode({ needResult: 1, // 預設為0,掃描結果由微信處理,1則直接返回掃描結果, scanType: ['qrCode', 'barCode'], // 可以指定掃二維碼還是一維碼,預設二者都有 success: function (res) { // 掃碼成功,跳轉到二維碼指定頁面(res.resultStr為掃碼返回的結果) // location.href = res.resultStr; var scan = res.resultStr if (isAndriod) { _this.$router.push({ path: '/exam_car', query: { id: scan } }) } else { setTimeout(() => { _this.$router.push({ path: '/exam_car', query: { id: scan } }) }, 500) } }, error: function (res) { if (res.errMsg.indexOf('function_not_exist') > 0) { alert('當前版本過低,請進行升級') } }, })
果然加了延時之後就好了。
第八步:掃碼結果處理
可能存在問題:
1、iOS裝置掃碼正常,Android裝置掃碼後沒反應
2、Android裝置掃碼正常,iOS裝置掃碼後沒反應
原因:微信開發文件並沒有說清楚,其實在微信後臺可能是維護了2個介面, 或者是對裝置型別進行了區別,總之在回撥函式中返回的結果封裝物件並不是同一個, 所以這要求我們也進行相應的處理, 不然就會出現上面這種預設奇妙的問題。
IOS 返回結果:
{ err_Info: 'success', resaultStr: 'XX', errMsg: 'scanQRCode:ok' }
Android 結果:
{ resaultStr: 'XX', errMsg: 'scanQRCode:ok' }
第九步:修改路由
本以為 蘋果安卓手機都能夠正常掃碼,沒問題了。但是領導換需求了,之前是掃碼放到外邊,可以匿名掃。現在要修改成登入之後才可以掃碼。
我就把路由修改了一下,先在登入頁登入成功之後,再進入掃碼頁,後臺也同步修改了 url 地址,修改完測試發現:
安卓的一切正常。
蘋果手機壞了!
奔潰了,看看錯誤提示:noPermissionJsApi:[],errMsg:"config:ok"。
確定之後有一個錯誤提示。
errMsg:scanQRCode:the perssion value is offline verifying
一頓百度猛如虎,半天原地打轉轉!
有前邊一次經驗教訓,我就又去找地址的原因。最後發現是竟然 $router.push 的跳轉影響了我的 url ,在 IOS 上的 push 跳轉不能寫入瀏覽器的位址列,但是安卓可以,導致安卓和 ios 跳轉之後的地址不同,所以 ios 失敗了。
解決辦法:
$router.push('/i') //修改成了 window.location = window.location.protocol + '//' + window.location.host + '/i'
此時就正常執行了。這下滿足專案要求了,不會再出什麼么蛾子了!
微信官方開發文件:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#4