一、创建WxResquest类
// 通过类的方式来进行封装,会让代码更具有复用性,也可以方便添加新的属性和方法
class WxResquest{
// 定义实例属性,用来设置默认请求参数
defaults={
baseURL:'',//请求基准地址
url:'',//接口的请求路径
data:null,//请求参数
method:'GET',//默认的请求方法
//请求头
header:{
'Content-type':'application/json'//设置数据的交互格式
},
timeout:60000//默认的超时时长,小程序默认的超时时长是1分钟
}
// 定义拦截器对象
// 需要包含请求拦截器以及响应拦截器,方便在请求之前以及响应以后时进行逻辑处理
interceptors={
// 请求拦截器
// request方法,在请求发送之前,对请求参数进行新增或修改
request:(config) => config,
// 响应拦截器
// response方法,在服务器响应数据以后,对响应的数据进行逻辑处理
reponse:(response) => response
}
// 用于创建和初始化类的属性以及方法
// 在实例化时传入的参数,会被constructor形参进行接收
constructor(params={}){
// 通过Object.assign方法合并请求参数
// 注意:需要传入的参数,覆盖默认的参数,因此传入的参数需要放到最后
this.defaults = Object.assign({},this.defaults,params)
}
// request实例方法接收一个对象类型的参数,属性值和wx.request方法调用时传递的参数保持一致
request(options){
// 需要先合并完整的请求地址(baseURL+url)
options.url = this.defaults.baseURL + options.url
// 合并请求参数
options={...this.defaults,...options}
// 在请求发送之前,调用请求拦截器,新增和修改参数
options = this.interceptors.request(options)
// 需要使用Promise封装wx.request,处理异步请求
return new Promise((resolve,reject)=>{
wx.request({
...options,
// 当接口调用成功时会触发success回调函数
// 接口调用错误,依然会走success
success:(res)=>{
// 不管是成功响应还是失败响应都需要调用响应拦截器
// 响应拦截器需要接受服务器响应的数据,然后对数据进行逻辑处理,处理好后进行返回,通过resolve将返回的数据抛出去
// 在给响应拦截器传递参数时,需要将请求参数也一起传递
// 方便进行代码的调试或者进行其他逻辑处理,需要先合并参数,然后将合并的参数传递给响应拦截器
// 在合并参数时,追加一个属性isSuccess,如果属性值为true说明执行了success回调函数,如果属性值为false说明执行了fail回调函数
const mergeRes = Object.assign({},res,{config:options,isSuccess:true})
resolve(this.interceptors.reponse(mergeRes))
},
// 当接口调用失败时会触发fail回调函数
// 当网络超时了,这时网络出现了异常就会执行fail
fail:(err)=>{
// 不管是成功响应还是失败响应都需要调用响应拦截器
const mergeErr = Object.assign({},err,{config:options,isSuccess:false})
reject(this.interceptors.response(mergeErr))
}
})
})
}
// 封装GET实例方法
get(url,data={},config={}){
// 需要调用request请求方法发送请求,只需要组织好参数,传递给request请求方法即可
// 当调用get方法时,需要将request方法的返回值return出去
return this.request(Object.assign({url,data,method:"GET"},config))
}
// 封装DELETE实例方法
delete(url,data={},config={}){
return this.request(Object.assign({url,data,method:"DELETE"},config))
}
// 封装POST实例方法
post(url,data={},config={}){
return this.request(Object.assign({url,data,method:"POST"},config))
}
// 封装PUT实例方法
put(url,data={},config={}){
return this.request(Object.assign({url,data,method:"PUT"},config))
}
}
export default WxResquest
二、实例化
import WxResquest from './request'
import {getStorage,clearStorage} from './storage'
import {model,toast} from './extendApi'
// 以下是实例化代码
// 对WxResquest进行实例化
const instance = new WxResquest({
baseURL:'https://blog.csdn.net',
timeout:15000
})
// 配置请求拦截器
instance.interceptors.request = (config) => {
// 在请求发送之前进行的逻辑处理
// 在发送请求之前,先判断本地是否存在访问令牌token
const token=getStorage('token')
// 如果存在token,需要在请求头中添加tokem字段
if(token){
config.header['token']=token
}
return config
}
// 配置响应拦截器
instance.interceptors.reponse =async (response) => {
// console.log(response)
// 从response中解构isSuccess,data
const {isSuccess,data}=response
// 如果isSuccess为false,说明执行了fail回调函数,这时说明网络异常,需要给用户提示网络异常
if(!isSuccess){
wx.showToast({
title: '网络异常请重试',
icon:'error'
})
return response
}
// 判断服务器响应的业务码
switch(data.code){
// 如果后端返回的业务状态码等于200,说明请求成功,服务器成功响应了数据
case 200:
// 对服务器响应数据进行的逻辑处理
return data
// 如果返回的业务码等于208,说明没有token,或者token失效
// 需要用户登录或者重新登录
case 208:
const res = await model({
content:'请重新登录',
showCancel:false //不显示取消按钮
})
if(res) {
// 清除之前失效的token,同时清除本地存储的全部数据
clearStorage()
wx.navigateTo({
url:'/pages/login/login'
})
}
return Promise.reject(response)
default:
toast({
title:'程序出现异常,请联系客服或稍后重试'
})
return Promise.reject(response)
}
}
// 将WxResquest实例进行暴露出去,方便再其他文件中进行使用
export default instance