近期接觸了小程式開發,發現我們可以使用微信小程式提供的介面來生成小程式二維碼,具體如何操作可以參見這裡:微信小程式獲取二維碼。 我們使用的是介面B: https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN 發 ...
近期接觸了小程式開發,發現我們可以使用微信小程式提供的介面來生成小程式二維碼,具體如何操作可以參見這裡:微信小程式獲取二維碼。
我們使用的是介面B:
https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
發現有個坑:未上線的小程式生成二維碼時如果傳入的page未上線,那麼會生成失敗。但是我們線上肯定是需要跳轉到指定頁面的,所以測試起來就比較蛋疼。各方咨詢,最終結果依然是未上線無法測試。。。
page要求:必須是已經發佈的小程式存在的頁面(否則報錯),例如 "pages/index/index" ,根路徑前不要填加'/',不能攜帶參數(參數請放在scene欄位里),如果不填寫這個欄位,預設跳主頁面
我們看一下微信官方提供的一些內容:
註意:通過該介面生成的小程式碼,永久有效,數量暫無限制。用戶掃描該碼進入小程式後,開發者需在對應頁面獲取的碼中 scene 欄位的值,再做處理邏輯。
使用如下代碼可以獲取到二維碼中的 scene 欄位的值。調試階段可以使用開發工具的條件編譯自定義參數 scene=xxxx 進行模擬,開發工具模擬時的 scene 的參數值需要進行 urlencode
// 這是首頁的 js Page({ onLoad: function(options) { // options 中的 scene 需要使用 decodeURIComponent 才能獲取到生成二維碼時傳入的 scene var scene = decodeURIComponent(options.scene) } })
也就是說我們可以在通過開發工具的條件編譯自定義參數模擬。這個方法我這邊沒有嘗試。
我們就按照最有可能正確的方式去做。對於後端是這樣傳值的:
scene = "uid=" + uid + "&cid=" + cid; Map<String, Object> twoDimensionMap = this.getTwoDimensionForWX(accessToken, page, scene);
其中的getTwoDimensionForWX是我們自定義的方法,裡面是調用微信的介面:
public Map<String, Object> getTwoDimensionForWX (String accessToken, String page, String scene){ Map<String, String> map = Maps.newHashMap(); Map<String, Object> resultMap = Maps.newHashMap(); map.put("page", page); map.put("scene", scene); Map<String, String> headers = Maps.newHashMap(); String method = "POST"; headers.put("Content-Type", "application/json; charset=UTF-8"); Map<String, String> querys = Maps.newHashMap(); String bodys = JSONObject.toJSONString(map); String host = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken; HttpResponse res =HttpUtils.doPost(host, "", method, headers, querys, bodys);
//res就是我們拿到的二維碼數據
}
這樣寫就可以成功獲取到二維碼(發佈線上之後), 因此後端發佈時這樣寫就ok。(這裡的方法只有一部分,並不完全,但完全可以表達出來意思)
接下來就是微信小程式端的處理:
onLoad: function (options) { // 掃描二維碼獲取的數據 if (options.scene) { var scene = decodeURIComponent(options.scene) // var scence = options.scene; var arrPara = scene.split("&"); var arr = []; var testData = {}; for (var i in arrPara) { arr = arrPara[i].split("="); if (i == 0) { testData.uid = arr[1]; } else { testData.cid = arr[1] } } //這裡的testData就包括了uid和cid } },
小程式端按照這種方式處理就可以了。
想想也是這個邏輯,微信那邊只是把scene做了encode處理,裡面的數據只是一個字元串,所以我們使用的時候後端傳的內容是什麼,我們小程式端取到的數據就是什麼,所以如果按照我上面呢的那種方式傳值,需要對字元串進行分割獲取需要數據。
另外需要註意一點:那就是scene的字元限制:
最大32個可見字元,只支持數字,大小寫英文以及部分特殊字元:!#$&'()*+,/:;=?@-._~,其它字元請自行編碼為合法字元(因不支持%,中文無法使用 urlencode 處理,請使用其他編碼方式)
以上便是對生成碼和掃碼的邏輯處理。