小程式–關於小程式未上線二維碼識別功能開發

zhanggui發表於2018-04-03

近期接觸了小程式開發,發現我們可以使用微信小程式提供的介面來生成小程式二維碼,具體如何操作可以參見這裡:微信小程式獲取二維碼

我們使用的是介面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 處理,請使用其他編碼方式)

 

以上便是對生成碼和掃碼的邏輯處理。

 

相關文章