请求拦截器本质上是在请求之前调用的函数,用来对请求参数进行新增和修改
响应拦截器本质上是在响应之后调用的函数,用来对响应数据做点什么。
创建拦截器的步骤如下:
整个流程是
- 声明拦截器(一个对象,包含请求响应拦截器)。
- 调用请求处理:发送请求之前调用请求拦截器处理。
- 调用响应处理:在
wx.request
的success
和fail
回调中,为 res 加上 isSuccess, 分别调用this.interceptors.response
方法来处理响应数据。 - 定义拦截器(在实例中定义):
-
- 请求拦截器:获取 token 并加入请求头;
- 响应拦截器:
-
-
- isSuccess 为 false 则为网络错误,若为 true,分情况
- code=200,正常返回 data;
- code=208,token 失效;
- 其余使用默认错误
-
声明拦截器
- 在
WxRequest
类中定义了一个interceptors
对象,该对象包含两个方法:request
和response
。这两个方法分别用于处理请求前和响应后的逻辑。
interceptors = {
// 请求拦截器
request: (config) => config,
// 响应拦截器
response: (response) => response
}
调用请求处理
- 在
request
方法中,在发送请求之前,通过调用this.interceptors.request
方法来处理请求配置。
// 在发送请求之前调用请求拦截器
options = this.interceptors.request(options)
调用响应处理
- 在
wx.request
的success
和fail
回调中,分别调用this.interceptors.response
方法来处理响应数据。
// 当接口调用成功时会触发 success 回调函数
success: (res) => {
// 不管接口成功还是失败,都需要调用响应拦截器
const mergeRes = Object.assign({}, res, { config: options })
resolve(this.interceptors.response(mergeRes))
},
// 当接口调用失败时会触发 fail 回调函数
fail: (err) => {
// 不管接口成功还是失败,都需要调用响应拦截器
const mergeErr = Object.assign({}, err, { config: options })
// 不管接口成功还是失败,都需要调用响应拦截器
err = this.interceptors.response(mergeErr)
reject(err)
}
定义拦截器
- 在实例化
WxRequest
类之后,可以通过修改instance.interceptors.request
和instance.interceptors.response
方法来配置具体的拦截器逻辑。
// 配置请求拦截器
instance.interceptors.request = (config) => {
// 在发送请求之前做些什么
return config
}
// 响应拦截器
instance.interceptors.response = (response) => {
// 对响应数据做点什么
return response.data
}
这样,拦截器就被成功添加到了 WxRequest
类中,并且可以在请求前和响应后执行自定义逻辑。在请求拦截器中,你可以修改请求配置,例如添加头部信息;在响应拦截器中,你可以根据响应数据进行一些处理,例如提取响应数据中的 data
属性。
下面是自定义逻辑:
- 请求拦截器:获取 token 并加入请求头;
- 响应拦截器:
-
- isSuccess 为 false 则为网络错误,若为 true,分情况
- code=200,正常返回 data;
- code=208,token 失效;
- 其余使用默认错误;
//在顶部引入
import {toast,modal}from './extendApi'
// 配置请求拦截器
instance.interceptors.request = (config) => {
// 从本地获取 token
if (wx.getStorageSync('token')) {
// 如果存在 token ,则添加请求头
config.header['token'] = wx.getStorageSync('token')
}
// 返回请求参数
return config
}
// 响应拦截器
instance.interceptors.response = async (response) => {
const { data, isSuccess } = response
if (!isSuccess) {
if (!isSuccess) {
toast({
title: '网络异常请重试',
icon: 'error'
})
// 抛出异常
return Promise.reject(response)
}
}
// 网络正常
switch (data.code) {
case 200:
// 接口调用成功,服务器成功返回了数据,只需要将数据简化以后返回即可
return data
case 208:
const res = await modal({
content: '鉴权失败,请重新登录',
showCancel: false
})
if (res) {
// 既然用户需要重新进行登录,就需要把之前用户存储的信息(过期的 token) 进行清除
// clearStorage()
wx.clearStorageSync()
wx.navigateTo({
url: '/pages/login/login'
})
}
default:
toast({
title: '程序出现异常,请联系客服或稍后重试!'
})
return Promise.reject(response)
}
}