最近項目有個需求是企業微信掃碼登錄,看過官方文檔后感覺挺簡單的,然而還是踩了好多坑,折騰了好久。。
在此記錄下遇到的坑。
URI的編碼
官方文檔的參數說明是這樣的
image.png
其中特別說明 'redirect_uri' 是需要進行Urlcode,我就天真地用window.encodeURI來編碼,當時的我并不知道還有window.encodeURIComponent,更別說兩者的區別了,因此就引發了一系列的問題!
- 掃碼成功后的重定向地址
因為用戶登錄后的一系列操作,比如獲取token、獲取用戶權限菜單等,都是在Login組件里進行的,因此我希望重定向的地址也是/login路由。
然而,重定向地址是: http://www.xxx.com/?code=xxx&state=xxx&appid=xxx#/login
重點是querystring的位置,當時一直很納悶,后來查閱了URI的標準,發現其標準規定querystring就是在錨點('#')之前的!
然后,這個url地址是一個空白頁,也就是說未匹配到任何路由? - window.location.href重定向的問題
由于加了一級路由后重定向到空白頁,因此我以為redirect_uri參數只識別域名(比較天真),就去掉了路由,將重定向地址變為: http://www.xxx.com
然后項目中路由的配置為 '/' 會被 redirect 到 '/index',然后/index路由對應的頁面有n個請求,axios攔截器又會根據是否登錄進行攔截,若未登錄,則用window.location.href重定向到http://www.xxx.com/#/login
按道理邏輯是這樣,但結果是axios攔截會失敗,也就是后面的請求的還會繼續進行,并且window.location.href = 'http://www.xxx.com/#/login' 這句代碼也執行了,最終導致的結果就是頁面會一直刷新且彈出錯誤警告。
但是,我將querystring加上,也就是 window.location.href = 'http://www.xxx.com/?code=xxx&state=xxx&appid=xxx#/login',也就就能正常跳轉!(至今還不清楚其中的原因,還是太菜了)
最后,將encodeURI改成了encodeURICompoent,一切就正常了!
重定向的地址變成了: http://www.xxx.com/#/login?code=xxx&state=xxx&appid=xxx
注意,querystring加在了路由的后面,也就是此時的querystring的并非URI標準中的querystring,而是vue-router中的querystring。而改變路由的querystring,是不會刷新頁面的,只會刷新組件,因此,只要在watch中監聽this.$route.query的變化,加上一些邏輯判斷即可!
watch: {
['$route.query'] (val) {
if (Object.keys(val).length) {
this.query = val;
this.qrcodeLogin();
}
}
}