原文發表於本人博客,點擊進入使用vue開發微信公眾號下SPA站點的填坑之旅
本文為我創業過程中,開發項目的填坑之旅。作為一個技術宅男,我的項目是做一個微信公眾號,前后端全部自己搞定,不浪費國家一分錢_。
我決定實現如下功能
- 架構上,實現前后端分離。方便以后前后端的分工
- 考慮到體驗,前端做成SPA站點,也就是單頁面應用
- 需要使用微信的JSSDK
- 需要有微信支付功能
作為一個偏后端的半專業前端人士,經過一兩周的調研和學習后,
我決定使用如下技術
- 后端使用php搭建接口,本文主要講前端,不細說
- webpack實現前端代碼打包
- vue實現數據綁定,vue-router實現前端路由
- weui提供UI框架
- vux,提供各種組件,包括對weui的組件化封裝
然后
我遇到了如下的坑
- 微信JSSDK簽名出錯
- 微信支付簽名出錯
- 微信支付路徑要求二級或以上路徑
- 開啟調試模式后,微信支付仍然沒有錯誤提示
- 授權回調處理
- 微信的模板消息,會自動把url中的問號(?)去掉
一一詳述
微信JSSDK簽名出錯
JSSDK在普通網站中是沒問題的,但是在SPA站點中,簽名經常出錯
JSSDK官方文檔是這么說的
所有需要使用JS-SDK的頁面必須先注入配置信息,否則將無法調用(同一個url僅需調用一次,對於變化url的SPA的web app可在每次url變化時進行調用,目前Android微信客戶端不支持pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題會在Android6.2中修復)。
也就是說,android下的微信客戶端里,不支持vue-router的history模式。
解決辦法見支付簽名問題
- vue-router使用hash模式
- 每次url更改的時候,重新調用JSSDK的config接口
微信支付簽名出錯
支付授權的坑,大家可以參考這篇文章
按照文中的描述,其實我們也可以在js中根據android還是ios,來分別進行處理;但是推薦采用文中的方式,邏輯上更統一,使用也更方便。
另外說明一點,文中的#!做分隔符的方式已經廢棄了,大家使用#即可,嘆號(!)去掉了
另外就是wx.config的簽名url和支付簽名url,微信處理也不一樣,見下面的解決辦法
解決辦法
- vue-router路由使用hash模式
- 每次url更改的時候,重新調用JSSDK的config接口
- hash分隔(#)前面加一個問號(?),如果js判斷沒有問號,則跳轉一次
- wx.config簽名使用的url,通過window.location.href.split('#')[0]獲取
- 微信支付簽名使用的url,通過用window.location.href獲取
微信支付路徑要求二級或以上路徑
在遇到這個問題之前,我的php接口都統一加了一個前綴api,也就是 **http://example.com/api/other 這樣的url,服務器會自動轉發給php服務,其他url則轉發給前端服務器。遇到微信這個問題后,我把前端url也統一加了一個前綴frontend,這樣前端url就變成了 **http://example.com/frontend/?#hash
解決辦法
- 所有前端url,統一加一個/frontend前綴
開啟調試模式后,微信支付仍然沒有錯誤提示
不止微信支付,JSSDK的其他接口,也經常沒有錯誤提示,或者提示很模糊,微信這簡直是慢性謀殺。
不過我對比發現,ios下的各種提示,要比android下全面很多,如有必要,推薦大家在ios下進行調試
解決辦法
- 使用iphone進行開發調試
授權回調處理
這個不算坑,只是說下我的處理。
每次加載頁面后,我都會調用后台接口判斷是否登陸,如果沒登陸,則跳轉回到后台url進行授權,授權后再跳轉回當前頁面
微信的模板消息自動去掉url的問號(?)
前面解決微信簽名問題的時候,我們給每個url特意加了一個問號(?),但是我發現,在發送微信模板消息的時候,即使給微信的url是對的,當用戶點擊模板消息的時候,微信打開的鏈接中,仍然把問號去掉了,這個很讓人無語。考慮到盡量自己解決問題的原則,最后我的解決方案是在js中進行判斷處理,自動把缺失的問號加上
解決辦法
- 如果頁面沒有問號(?),則跳轉到正確的url,代碼如下
function directRightUrl () {
let paths = window.location.href.split('#')
paths[1] = paths[1] || '/'
// 老式的#!分隔跳轉
if (paths[0].charAt(paths[0].length - 1) !== '?') {
paths[0] = `${paths[0]}?`
}
if (paths[1].charAt(0) === '!') {
paths[1] = paths[1].substr(1)
}
let url = `${paths[0]}#${paths[1]}`
if (window.location.href !== url) {
window.location.href = url
}
}
以上代碼有三個作用
- 自動添加問號(?)
- 自動把分隔符由#!變成#
- 分隔符后面,自動判斷是否為斜杠(/),沒有則添加上
結束語
以上就是我在開發過程中遇到的一些還記得的坑,歡迎大家探討
另外介紹一下我的公眾號啟奏陛下
這是一個提供“一句話新聞”的公眾號,沒有標題,標題即內容
掃描以下二維碼可以關注

