二維碼問題上的一些思考

KeMo發表於2019-03-03

微信掃碼調研

調研微信的掃碼功能發現現在微信對於自家的二維碼有幾種掃碼模式。

一種是http/https連線,這種連線的話微信會通過瀏覽器呼叫然後再做資訊注入(有必要的話)。
如微信網頁二維碼登入:

微信網頁掃碼登入

其二維碼對應的內容為:
https://login.weixin.qq.com/l/gbhwtYZltA==

另一種是通過特殊協議,也可以叫Scheme URL,如微信支付中,二維碼對應內容為:

wxp://f2f0PGHjdQNdT3lenn6DVlwq_Sg0aDGIE_Ia

而對於第三方二維碼,微信的處理方式是判定是不是一個網址,如果是網址就會跳轉瀏覽器,如果不是網址則直接將二維碼對應內容顯示出來。

延伸

對於登陸,還是這個連結https://login.weixin.qq.com/l/gbhwtYZltA==,當你用瀏覽器開啟時你會發現跳轉到一個顯示無法識別的二維碼的頁面,然後點選上面的現在升級,接下來神奇的事情發生了,它居然直接轉向蘋果的AppStore,可是我這是個Android裝置,UA都是Android。

看過一篇文章說微信二維碼功能設計的妙處,就是通過UA來判定要進行下一步的操作,在微信聯絡人二維碼中,如果判定到是微信客戶端則直接調起新增聯絡人,如果判定到是Android裝置就會跳轉微信下載apk的地址,那篇文章大家可以去看看。

產品經理小技術(三):二維碼這把利刃,產品應該用到極致 – 簡書

只是現在微信已經不支援這麼幹了,我直接使用MIUI瀏覽器掃聯絡人二維碼時只出現了以下這個畫面:

二維碼問題上的一些思考

改進點思考

對於微信的二維碼,看似是退步了,畢竟之前識別UA的方式會更加完善各種使用場景,但也許微信是出於安全考慮去掉了這種方式。這裡不討論微信的問題,而討論下怎麼去完善二維碼的使用場景。

應對外部掃碼說明網頁

首先,通過UA智慧判斷場景是一種方式,這種方式上面提到的文章中也已經闡述地很清楚了,這裡就不細說了。

另一種方式是對UA智慧判斷的擴充。

首先需要一個二維碼說明/app下載介紹的網頁,譬如這個網頁是:https://www.baidu.com/code (舉個例子,不要當真)
那麼使用者訪問這個網頁的時候,就會看到app的下載資訊,這個時候使用者可以點選下載(UA就派上用場了,判斷UA是Android或iPhone來跳轉對應下載頁面)。

然後這就完了?

並沒有。

定義需要在二維碼攜帶的資訊結構

需要在二維碼中定義一些只有自家APP來識別的資訊,實現類似微信掃付款碼就自動調起支付功能。

對資訊進行分組是第一步,先按資訊型別,來分組不同的action

用微信的場景分析,假定有三個場景如下:

場景value 場景說明
pay 支付的動作
contact 新增聯絡人的動作
login 掃碼登陸的動作

有對應的動作(action),那麼肯定也會有這些動作需要攜帶的引數,以微信自身二維碼為例,開頭提到的兩個二維碼攜帶的資訊分別如下:

  • 掃碼登陸:https://login.weixin.qq.com/l/gbhwtYZltA==
  • 微信支付:wxp://f2f0PGHjdQNdT3lenn6DVlwq_Sg0aDGIE_Ia

注意我加了強調的部分,這部分很明顯是這個二維碼攜帶資訊的至關重要的點,我把它理解為uid

所以一個二維碼不僅要攜帶action來標識要客戶端掃碼後的相應的動作,還需要攜帶這個動作所需要的引數uid,當然上述場景的action只用到了uid,如果換成別的場景,比如跳轉一個小遊戲的網頁,那麼攜帶過來的引數就是一個url了。

當然引數不是固定的,可以根據自身專案的引數結構進行適當調整,抽出一個通用跳轉動作的結構。

回到剛剛提到的結構,根據上述說明可以把結構整理成json資料如下:

{
"action":"wxp",
"uid":"gbhwtYZltA==",
"url":null
}
複製程式碼

將攜帶的資訊整合進URL

前面應對外部掃碼說明網頁一節中提到的url:https://www.baidu.com/code ,這裡再次提出來,然後我們需要將上述二維碼攜帶的資訊結構整合進這個url,就得到如下結果:

https://www.baidu.com/code?param={“action”:”wxp”,”uid”:”gbhwtYZltA==”,”url”:null}

很明顯,這肯定不能作為url存在,有種方式是對param的內容做urlencode,客戶端解析後再對相應內容進行decode。

還有種方式,對param引數後面的內容進行base64處理,待處理的內容為:

{“action”:”wxp”,”uid”:”gbhwtYZltA==”,”url”:null}

base64處理後的內容為:
eyJhY3Rpb24iOiJ3eHAiLCJ1aWQiOiJnYmh3dFlabHRBPT0iLCJ1cmwiOm51bGx9

有了這串內容後,整合後的url結果就是這樣滴:

https://www.baidu.com/code?param=eyJhY3Rpb24iOiJ3eHAiLCJ1aWQiOiJnYmh3dFlabHRBPT0iLCJ1cmwiOm51bGx9

最後再用這個url生成個二維碼:

二維碼問題上的一些思考

掃碼後的處理

掃碼後處理分兩種形式:

  1. 自有客戶端掃碼
  2. 第三方app掃碼

自有客戶端掃碼

因為規則是自己定的,所以在客戶端裡面掃碼,只需要按照規則解析,拿到最終二維碼想要給客戶端的資訊做進一步操作就可以了。

對於自產二維碼步驟大致如下:

  1. 客戶端掃碼,解析二維碼
  2. 判斷到url是客戶端專有二維碼連結(具體可利用正則,甚至簡單粗暴字串匹配,但規則最好由服務端下發,保證可更新性),解析對應param引數的值
  3. base64 decode param引數
  4. 解析param引數的json字串,組裝結構,根據action和引數做進一步操作

但既然客戶端做了掃碼功能,說不定使用者就會拿起客戶端直接用這個功能掃別家的二維碼,這個時候也許是一個網址,也許是一個特殊協議的url,這個時候可以根據自身需求做網頁跳轉處理或者不處理。

第三方app掃碼

針對這種情況,一個有效的可以訪問的網址就排上用場了,以上述例子網址為例,第三方app掃碼後只要是發現是http或https協議的,一般都會跳轉到內建/外接瀏覽器開啟,那麼只要保證https://www.baidu.com/code這個地址能訪問就ok了,至於這個網址你是放個“此二維碼不受外部應用支援”,還是放個app下載介紹,還是根據UA直接重定向到下載apk地址/appStore,那都是按需操作的事情了。

以上就是關於二維碼問題的思考,如果有對這個問題有更好的想法的可以提出來大家碰撞下。

相關文章