uni-app跨端開發之生成小程序碼和調試scene參數爬坑指南


作者:藝靈設計 - 來源:http://www.yilingsj.com - 發布時間:2020-12-26 22:34:31 - 閱:872 - 評:0 - 積分:0

摘要:生成微信小程序碼的前提條件是小程序必須要上線,相信很多開發者光是看到這一條就已經震驚到了。而且小程序碼中的scene最多可以攜帶32個字符,關鍵是難調試。另外,雖然前端也可以自己生成微信小程序碼,但有坑......

前段時間,公司的小程序中有一個分享小程序碼邀請好友的功能。前前后后也踩過不少坑,然后就有了這篇筆記。如果看官正在因生成微信小程序碼或調試scene參數而苦惱,不妨繼續往下看看,或許這篇文章能夠幫助到您喲。

1、如何生成微信小程序碼

在微官方文檔中,一共提供了三種生成小程序碼的API接口,場景和限制各不相同。如下表格:

生成小程序碼的三個接口
API 解釋 攜帶參數
wxacode.createQRCode訪問文檔 獲取小程序二維碼,適用於需要的碼數量較少的業務場景。永久有效,有數量限制 path,最大長度 128 字節
wxacode.get訪問文檔 獲取小程序碼,適用於需要的碼數量較少的業務場景。永久有效,有數量限制 path,最大長度 128 字節
wxacode.getUnlimited訪問文檔 獲取小程序碼,適用於需要的碼數量極多的業務場景。永久有效,數量暫無限制。 scene, 最大32個可見字符
可以看到前兩個接口生成的小程序碼都有 數量限制,最后一個是沒有的。考慮到日后的業務量,我毫不猶豫的選擇了 wxacode.getUnlimited。然后,一系列的坑就隨之而來。若看官在項目中使用的是前兩種接口,可以不用繼續往下看了。

 

1.1、前端生成 VS 后端生成

在剛開始的時候,我使用的是前端生成的方式。事實證明,這種方式是錯誤的,盡管前端也可以成功生成小程序碼。在小程序中直接訪問文檔中給出的接口地址
https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token= 
結果返回的錯誤碼為41030。查看文檔得知,此錯誤碼表示小程序未發布。再查看官方的文檔,發現明確指出path必須是已經發布的小程序存在的頁面(否則報錯)。如圖:path必須是已經發布的小程序存在的頁面.pngpath必須是已經發布的小程序存在的頁面

不發布又生成不了小程序碼,發布的話相當於發布的版本中生成小程序碼的功能不能使用,簡直是個流氓!后來又拖了好久,某日,我決定發版並測試下小程序碼。

發版很順利,大概在提交后40分鍾左右的時候,微信上來消息說發版通過了。我當時激活的不得了,立即在本地環境上跑了下小程序,點擊分享按鈕發現沒反應。查看請求,一切正常且請求返回的是一張圖片,當時一臉黑人問號...... 如圖:getwxacodeunlimit接口成功返回小程序碼但前端無法渲染.pnggetwxacodeunlimit接口成功返回小程序碼但前端無法渲染

1.2、返回二進制圖片數據后如何顯示到頁面上?

什么鬼?你直接給我圖片,我怎么顯示到頁面上???

后來才知道,原來請求時需要設置responseType: 'arraybuffer',此時接口在成功時會返回圖片的二進制數據。然后前端這邊再通過
uni.arrayBufferToBase64(arrayBuffer)
即可將二進制圖片轉換成base64,最終成功顯示在頁面上。如圖:解析二進制圖片時需要設置arraybuffer和arrayBufferToBase64.png解析二進制圖片時需要設置arraybuffer和arrayBufferToBase64

到目前為止,整個生成小程序碼的操作全靠前端完成。為了防止生成小程序碼失敗,我還給項目鍍金,添加了一個刷新的功能。就是當生成失敗時,用戶可以點擊小程序碼占位區進行手動生成。效果如圖:手動刷新小程序碼.gif手動刷新小程序碼

2、讓人頭大的scene

2.1、拼接scene參數

由於受接口getUnlimited的限制,page只能是純路徑,而想要攜帶參數只能放到scene中。這個方案看似還不錯,至少解決了攜帶參數的問題。但攜帶參數長度有限制,且需要根據情況進行轉碼。好在我們分享的參數不需要轉碼,直接拼接即可。當時我們的代碼是這樣的:
this.scene = '?invite=' + res.data.key /* 邀請碼中攜帶的參數 */

2.2、掃碼后解析scene參數

按照正常流程,上一步生成了帶參數的小程序碼。當用戶長按識別了小程序碼或通過掃碼進入小程序時,我們在指定的path頁面中需要解析scene參數。若不解析的話,我們就無法做到數據統計,也就無法在該用戶的邀請記錄中清晰的展示邀請了哪些用戶。如圖:分享小程序碼后可以查看邀請記錄.png分享小程序碼后可以查看邀請記錄

在頁面生命周期中,onLoad可以獲取到當前地址中攜帶的參數。所以,解析scene的操作要在onLoad函數中進行。由於我們的小程序中多處用到了分享功能且path也不同,所以我把解析scene的代碼封裝成了一個方法。大致代碼如下:

  1. /* 將url中的參數轉成對象{key:value}的形式,方便讀取 */
  2. function urlParams (scene) {
  3.   const str = decodeURIComponent(scene).replace('?', '&')
  4.   let strArr = str.split('&')
  5.   strArr = strArr.filter(item => item)
  6.   const result = {}
  7.   strArr.filter(item => {
  8.     const key = item.split('=')
  9.     result[key[0]] = key[1]
  10.   })
  11.   return result
  12. }

調用的話也非常簡單,示例代碼如下:

  1. import { urlParams, } from '@/common/util' /* 先引入方法 */
  2. onLoad (options) {
  3.   if (Object.keys(options).length) {
  4.     const { invite, scene } = options
  5.     if (scene) { /* 掃碼進來 */
  6.       const sceneObj = urlParams(scene)
  7.       if (sceneObj.invite) {
  8.         this.invite = sceneObj.invite /* 邀請碼 */
  9.       }
  10.     }
  11.     /* 正常情況,包括H5端、APP端 */
  12.     if (invite) {
  13.       this.invite = invite
  14.     }
  15.     ...... /* 其他代碼 */
  16.   }
  17. }

這樣,當用戶掃碼進時我們就能成功的解析出小程序碼中攜帶的參數了。然后需要上報就上報,該干嘛干嘛,一切看似都很美好。但這只是我們假設的順利場景,並沒有經過真正的校驗。

2.3、解析scene

如何校驗呢?雖然我們本地是可以成功的生成了小程序碼,但當你分享給同事后,同事識別小程序碼進入時會直接進入到了線上版本。划重點哈,是跳轉到了線上版本。前面已經說了,我們線上版本中對應的path頁面還沒有添加解析scene的代碼哈。

那怎么解決這個問題呢?最笨的方法就是:把本地的小程序打包發版,然后再測。而這個方法的弊端也很明顯,如果我們在封裝urlParams函數時考慮不周或者是上報接口還不確定,再或者scene中有字符需要轉碼而忘記了轉碼,那就會導致我們面臨不停發版來改bug的困境!再想想去年的自己,真是被自己給蠢哭了!

那有沒有更好的解決方案呢?

2.3.1、開發者工具中選擇二維碼編譯

答案是有的。在微信小程序開發者工具中,我們可以通過上傳二維碼實現本地解析。如圖:在微信開發者工具中通過二維碼編譯可直接調試攜帶參數scene.png在微信開發者工具中通過二維碼編譯可直接調試攜帶參數scene通過上圖可以看到,成功的解析並在login.vue文件中的onLoad函數中第115行監聽到了scene。本地調試比起線上發版,是不是非常便利呀!

2.3.2、開發者工具中構造scene編譯

除此之外,我們也可以通過在本地直接構造scene參數來模擬掃碼訪問,節省調試時間。相關代碼結構如下:
scene=encodeURIComponent(參數)
如圖:在開發者工具中手動構造scene.png在開發者工具中手動構造scene

現在,我們已經可以在本地肆無忌憚的構造scene和解析scene,再也不用靠發版來調試了,簡直爽歪歪!那事情是不是就已經結束了呢?顯然沒有。畢竟我們的項目最終還是要上線的,那再發一版到線上測試下效果吧!

3、發版后不顯示小程序碼?

通過HBuilder X將項目進行打包,打包完畢后繼續上線。由於每次審核需要一些時間,看官可以先去干點別的。

大約又過了40來分鍾,微信上再次提醒審核通過了。我依舊是迫不及待的對分享小程序碼進行了測試,結果翻車了!小程序碼不顯示!!即使我通過手動刷新也不顯示!!!此時的我一臉懵逼!明明測試版沒問題呀,怎么到線上就翻車啥都不顯示呢?而且開啟調試后,接口也不報錯!這回我徹底懵逼了......

如果看官也遇到了此問題,想必看官跟藝靈的做法是一樣的,即:生成二維碼的操作由前端完成。其實這個操作是錯誤的,盡管微信官方並沒有特殊強調必須要由后端生成

3.1、必須小程序碼由后端生成

既然需要后端生成,那就讓后端老哥寫個接口唄。我把要攜帶的scene參數和要訪問的path參數傳遞給他的接口,他拿去請求接口生成小程序碼並返回給我,我這邊再使用uni.arrayBufferToBase64()對返回數據進行解析即可。

這里需要注意的是,我們在請求后端接口的時候同樣需要在請求中帶上arraybuffer: true,若看官使用的是原生的uni.requestwx.request的話,需要添加responseType: 'arraybuffer',才能成功的解析二進制圖片,否則解析不成功哦!

四、代碼演示

由於項目代碼比較復雜,這里只簡單做下展示。

  1. /* 獲取小程序碼 */
  2. handleGetXcxQrcode () {
  3.   const data = {
  4.     scene: this.scene, /* url中攜帶的參數 */
  5.     page: 'pages/user/login' /* 掃碼后跳轉的訪問頁面 */
  6.   }
  7.   uni.request({
  8.     url: '后端生成小程序碼后暴露給前端的API地址',
  9.     data: data,
  10.     responseType: 'arraybuffer', /* 必須 */
  11.     success: (result) => {
  12.       const res = result.data
  13.       uni.hideLoading()
  14.       if (res.errcode === 41030) {
  15.         setTimeout(() => {
  16.           uni.showToast({ title: '請先發布小程序', icon: 'none' })
  17.         }, 0)
  18.       } else if (res.errcode === 45009) {
  19.         setTimeout(() => {
  20.           uni.showToast({ title: '調用頻繁', icon: 'none' })
  21.         }, 0)
  22.       } else {
  23.         const url = 'data:image/png;base64,' + uni.arrayBufferToBase64(res)
  24.         if (uni.arrayBufferToBase64(res)) {
  25.           this.wxQrcode = url
  26.         }
  27.       }
  28.     }
  29.   })
  30. },

4.1、源碼下載

如果您想查看完整源碼,可以猛戳下方的鏈接進行訪問。

  1. 網址: 戳我前往github查看源碼

五、最后

最后來總結下生成微信小程序碼需要注意的事項:
1、必須由后端提供小程序碼,前端雖也能直接生成,但線上版本無法生成;
2、在請求中需要添加responseType: 'arraybuffer',參數;
3、在請求成功后前端無法直接顯示圖片,需要使用uni.arrayBufferToBase64(res)將 ArrayBuffer 對象轉成 Base64 字符串;
4、通過微信開發者工具中提供的二維碼編譯編譯模式,我們可以在本地構造和解析小程序碼,無需頻繁發版。

轉載聲明:
  若親想轉載本文到其它平台,請務必保留本文出處!
本文鏈接: http://www.yilingsj.com/xwzj/2020-12-26/uni-app-wxacode-getUnlimited.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM