微信小程序原生的网络请求we.request,存在以下几个问题
当发生多层网络请求嵌套时,代码结构很差,需要改写成promise形式
有的接口需要用户登录,即携带token(用户登录成功后,后台返回的token,存储在小程序中)才能进行访问,否则会返回认证失败,所以要解决2个问题,1是自动携带token,2是认证失败最好重新登录重新进行访问
网络请求经常用到,现在的写法很多都是重复的
所以我们必须对网络请求进行封装。
封装的请求流程大致如下
检查是否有网络,无网络提醒稍候重试
如果有网络发起请求,请求时携带token到header的Authorization中
如果返回数据code==1001(认证失败的错误码,根据自己情况改写),则重新进行登录操作
a. 调用wx.login获取code
b.调用后台的login接口,登录成功返回token
c.将token存储到本地
d.再次发起网络请求
如果返回数据code==1(成功),调用成功回调
其他情况 调用失败回调
源码如下,其中所有的小程序接口均已改成promise形式,见 shanhuxueyuan.com/news/detail…
var wxapi = require("../network/base.js").wxapi; var api=require("../network/config.js").api;
const method={ post: "POST", get: "GET" }
function fetch({ url, data = '', method='POST'}){ return new Promise((resole,reject)=>{ wxapi("getNetworkType") .then(res=>{ if (res.networkType=="none"){ wx.showToast({ title: '网络好像不太好哦,请稍候再试', icon: "none" }) }else{ wxapi("request", { url: api.base_url + url, header: { 'Authorization': 'Bearer ' + wx.getStorageSync('token'), 'content-type': 'application/x-www-form-urlencoded' // 默认值 }, data: data, method: method, }) .then(res => { if (res.data.code == 1001) { //认证失败,重新登录 wx.showToast({ title: '验证失败,自动重试', icon:"none"
})
wxapi("removeStorage", { key: "token" })
.then(() => wxapi("login"))
.then(res => fetch({
url: api.login,
data: {
code: res.code
},
})
)
.then(res => {
if (res.code == 1) {
//登录成功,重新请求一次
wx.setStorageSync('token', res.data.token)
wxapi("request", {
url: api.base_url + url,
header: {
'Authorization': 'Bearer ' + wx.getStorageSync('token'),
'content-type': 'application/x-www-form-urlencoded' // 默认值
},
data: data,
method: 'POST',
})
.then(res => {
if (res.data.code == 1) {
resole(res.data)
} else {
reject(res.data)
}
})
}
})
} else if (res.data.code == 1) {
//成功
resole(res.data)
} else {
//失败
reject(res.data)
}
}).catch(res => {
reject(res.data)
})
}
})
}) }
module.exports = {fetch, method} 在页面中调用
var network=require("../../utils/network/network.js") var wxapi = require("../../utils/network/base.js").wxapi; var api = require("../../utils/network/config.js").api;
Page({
onLoad: function () {
network.fetch({
url: api.course_detail,
data: {
id: 18
},
})
.then(res=>{
console.log(res);
})
.catch(res=>console.log(res))
},
}
})
接口地址,放在config.js中
const api={ base_url: 'https://****.com', login: '/v1/user/login', course_detail: '/v1/course/detail', }
module.exports={api}
base.js 将微信的api封装成promise形式
function wxapi(function_name, obj) { return new Promise((resole, reject)=>{ wx[function_name]({ ...obj, success: res => resole(res), faile:res=>reject(res) }) }) }
module.exports = {wxapi}