最近因(yin)為公司業務一直(zhi)在做微信小程序的項目,趁此機會將最近踩過的一些坑總(zong)結記錄下。

appid 小(xiao)程(cheng)(cheng)序唯一標識 secret 小(xiao)程(cheng)(cheng)序的(de) app secret js_code 登(deng)錄時獲取(qu)的(de) code grant_type 填寫為 authorization_code
openid 用(yong)戶(hu)唯一標識(shi) session_key 會(hui)話密鑰
openid 是用(yong)(yong)戶(hu)唯(wei)一標識,但(dan)不建議直接用(yong)(yong)做后(hou)端服務(wu)器的(de)各用(yong)(yong)戶(hu)標示(shi)符(fu)。 session_key 是針對用(yong)(yong)戶(hu)數據進行加密(mi)簽名的(de)密(mi)匙。session_key 在文件(jian)校驗,獲取用(yong)(yong)戶(hu)具體信息時均需(xu)使用(yong)(yong)
一般為了(le)安全起見(jian),這兩個(ge)數據都不會發往客戶(hu)端。
//app.js
const NOLOGINCODE = 1000003 //未登錄
const SUCCESS = 1000001 //成功
App({
onLaunch: function () {
var loginFlag = wx.getStorageSync('sessionId');
var that = this;
if (loginFlag) {
// 檢查 session_key 是否過期
wx.checkSession({
// session_key 有效(未過期)
success: function () {
var userInfo = wx.getStorageSync('wxUserInfo')
if (userInfo) {
that.globalData.hasUserInfo = true
}
},
// session_key 過期
fail: function () {
// session_key過期,重新登錄
that.doLogin();
}
});
} else {
// 無skey,作為首次登錄
this.doLogin();
}
},
doLogin() {
this.log().then(res => {
this.$post('/auth', { code: res.code, }, false).then(data => {
wx.setStorageSync('sessionId', data.sessionId);
})
})
},
/**
*微信登錄 獲取code值,并將code傳遞給服務器
* @returns
*/
log() {
return new Promise(resolve => {
wx.login({
success(res) {
if (res.errMsg === "login:ok") {
resolve(res)
} else {
wx.showToast({
title: '微信登錄失敗',
icon: 'none',
duration: 1200
})
}
},
fail() {
wx.showToast({
title: '微信登錄接口調用失敗',
icon: 'none',
duration: 1200
})
}
})
})
},
globalData: {
baseurl: '//www.fake.shop'
}
})
復制代碼
微信小(xiao)程序中網絡(luo)請(qing)求(qiu)(qiu)的api是(shi)wx.request(),但是(shi)這個(ge)請(qing)求(qiu)(qiu)是(shi)個(ge)異(yi)步回調的形式,每次發請(qing)求(qiu)(qiu)都要(yao)寫(xie)好長一串,而且如果是(shi)嵌套(tao)的發請(qing)求(qiu)(qiu),就會發現代碼寫(xie)的及其(qi)臃腫,所以將其(qi) Promisefy是(shi)及其(qi)有必要(yao)的。 代碼如下:
$get(url, data = {}, needToken = true) {
let SUCCESS = 200
var that = this
needToken ? (data.token = wx.getStorageSync('ToKen')) : ''
return new Promise((resolve, reject) => {
wx.request({
url: that.globalData.baseurl + url,
method: "GET",
header: {
'content-type': 'application/json'
},
data: data,
success(e) {
if (e.data.code == SUCCESS) {
resolve(e.data)
return
}
},
fail(e) {
wx.showModal({
title: '提示',
content: '請求失敗',
showCancel: false
})
reject(e)
}
})
})
},
$post(url, data = {}, needToken = true) {
let that = this
let SUCCESS = 200
let TimeOut = 1000
var that = this
needToken ? (data.token = wx.getStorageSync('ToKen')) : ''
return new Promise((resolve, reject) => {
wx.request({
url: that.globalData.baseurl + url,
method: "POST",
//此處可以根據接口文檔設置header頭
// header: {
// 'content-type': 'application/x-www-form-urlencoded'
// },
data: data,
success(e) {
if (e.statusCode == SUCCESS) {
if (e.data.code == SUCCESS) {
resolve(e.data)
}
else {
reject(e)
wx.showModal({
title: '提示',
content: e.data.msg,
showCancel: false,
success: function (res) {
if (res.confirm) {
if (e.data.code == TimeOut) { //根據實際業務返回的code碼判斷是否過期
// 登錄過期
that.doLogin();
}
}
}
})
}
} else {
wx.showModal({
title: '提示',
content: e.data.error,
showCancel: false
})
reject(e)
}
},
fail(e) {
console.log(e)
wx.showModal({
title: '提示',
content: '請求失敗',
showCancel: false
})
reject(e)
},
complete(e) {
}
})
})
},
復制代碼
雖然是(shi)寫(xie)小程序踩(cai)坑(keng)指南,但是(shi)在微信內(nei)的H5頁面支付和小程序內(nei)掉起支付還是(shi)有(you)相似(si)之(zhi)處的,順便(bian)記錄一(yi)下。
UnionID:為(wei)了識別用(yong)戶(hu)(hu)(hu),每個(ge)(ge)(ge)用(yong)戶(hu)(hu)(hu)針對每個(ge)(ge)(ge)公(gong)(gong)眾(zhong)號(hao)會(hui)產生一(yi)(yi)(yi)個(ge)(ge)(ge)安全的(de)(de) OpenID,如果需(xu)要在多(duo)公(gong)(gong)眾(zhong)號(hao)、移動(dong)應(ying)用(yong)之間做用(yong)戶(hu)(hu)(hu)共通(tong),則需(xu)前(qian)往微(wei)(wei)信(xin)(xin)(xin)開(kai)(kai)放(fang)平(ping)(ping)臺(tai),將(jiang)這些(xie)公(gong)(gong)眾(zhong)號(hao)和(he)應(ying)用(yong)綁(bang)定到一(yi)(yi)(yi)個(ge)(ge)(ge)開(kai)(kai)放(fang)平(ping)(ping)臺(tai)賬號(hao)下,綁(bang)定后,一(yi)(yi)(yi)個(ge)(ge)(ge)用(yong)戶(hu)(hu)(hu)雖然對多(duo)個(ge)(ge)(ge)公(gong)(gong)眾(zhong)號(hao)和(he)應(ying)用(yong)有(you)多(duo)個(ge)(ge)(ge)不同(tong)的(de)(de) OpenID,但(dan)他(ta)對所有(you)這些(xie)同(tong)一(yi)(yi)(yi)開(kai)(kai)放(fang)平(ping)(ping)臺(tai)賬號(hao)下的(de)(de)公(gong)(gong)眾(zhong)號(hao)和(he)應(ying)用(yong),只有(you)一(yi)(yi)(yi)個(ge)(ge)(ge) UnionID 網(wang)頁授權: 一(yi)(yi)(yi)些(xie)復雜的(de)(de)業務場(chang)景下,需(xu)要以網(wang)頁的(de)(de)形式(shi)提(ti)供(gong)服(fu)務,通(tong)過網(wang)頁授權可以獲(huo)取(qu)用(yong)戶(hu)(hu)(hu)的(de)(de)openid(注:獲(huo)取(qu)用(yong)戶(hu)(hu)(hu)的(de)(de) OpenID 是無需(xu)用(yong)戶(hu)(hu)(hu)同(tong)意的(de)(de),獲(huo)取(qu)用(yong)戶(hu)(hu)(hu)的(de)(de)基本(ben)信(xin)(xin)(xin)息則需(xu)用(yong)戶(hu)(hu)(hu)同(tong)意) 微(wei)(wei)信(xin)(xin)(xin) JS-SDK:是開(kai)(kai)發者在網(wang)頁上通(tong)過 JavaScript 代碼(ma)使用(yong)微(wei)(wei)信(xin)(xin)(xin)原生功能的(de)(de)工(gong)具包,開(kai)(kai)發者可以使用(yong)它在網(wang)頁上錄制和(he)播放(fang)微(wei)(wei)信(xin)(xin)(xin)語音(yin)、監聽微(wei)(wei)信(xin)(xin)(xin)分享(xiang)、上傳手機本(ben)地(di)圖(tu)片(pian)、拍照(zhao)等(deng)許多(duo)能力。

npm install weixin-js-sdk ;
var wx = require('weixin-js-sdk');
URLEncoder.encode(payUrl)是非常有必要的 state參數: 用于保持請(qing)求和回調(diao)的狀態,授權請(qing)求后原(yuan)樣帶(dai)回給第三(san)方。該參數可用于防止(zhi) csrf 攻擊(跨站請(qing)求偽造攻擊),建(jian)議第三(san)方帶(dai)上該參數,可設(she)置為簡單的隨機數加 session 進行校驗 后端(duan)獲取openid的原(yuan)因: 因為我是前端(duan),不想(xiang)搞這個(開玩笑的