前言:最近在写小程序的时候初步使用了下wx.request感觉捡漏了点,想实现一些全局拦截的功能,但这东西似乎没有个统一的标准,不像axios那样,为什么不用axios?额...听说好像不支持axios,我也是听说哈,搜索了一些文章每个人都有自己的一套代码,把他们代码理顺的时间都够自己封装一套了,杂乱无章的代码看得我很是打脑壳,如果你告诉我去看那官网文档,我嘞个豆,还是自己封装吧
废话不多说,先看一下使用效果,简直就是傻瓜式操作啊!复制粘贴就能用,小白也能懂,当然我也是小白
可以看到报了个错,因为后端没开,接口调不通的错误是拦截不到的,这就是为什么没打印响应拦截log的原因。全局拦截注册方式和axios很像,既简单又方便,这是简单封装后的源码我放在下边,不过你应该注意一些规则,稍后我会说
//封装了一下请求,让他多了个请求和响应拦截功能以及baseURL功能
function Request(options) {
const refURL = options?.url
//一些静态方法
//获取除去baseURL的请求地址
Request.getRequestURL = function () {
return refURL
}
//设置请求头
Request.setRequestHeader = function (name, value) {
if (!options.header) {
options.header = {}
}
options.header[name] = value
}
//获取请求头
Request.getRequestHeader = function (name) {
return options['header'][name]
}
//获取所有请求头
Request.getAllRequestHeader = function () {
return options['header']
}
//如果设置了请求拦截器
try {
const newRequest = Request.interceptor.request.use(options), baseURL = Request.defaults.baseURL
if (!newRequest) return //如果请求拦截内没有返回新的request 则不做请求 一种优化
options = newRequest
options.url = baseURL + refURL
} catch(err) {}
//如果设置了响应拦截
try {
const root = Request?.interceptor,
responseInvoke = root?.response?.use, //全局响应拦截 请求成功才触发
adviceError = root?.error?.use, //全局异常拦截器
adviceFinally = root?.complete?.use, //全局执行完后回调器
{ success, fail, complete } = options //这里可以起到回调缓存作用 提前缓存 后面会从options中删除
//有任何响应拦截器都会进入代理执行
if (root && (responseInvoke || adviceError || adviceFinally)) {
//如果有回调先删除 进行代理托管
if (success) {
delete options.success
}
if (fail) {
delete options.fail
}
if (complete) {
delete options.complete
}
//建立新options
const newOptions = {
success(response) {
let newResponse = responseInvoke(response)
if (success) {
success(newResponse)
}
},
fail(error) {
let newError = error
if (adviceError) {
newError = adviceError(error)
}
if (fail) {
fail(newError)
}
},
complete(never) {
let finallys = never
if (adviceFinally) {
finallys = adviceFinally(never)
}
if (complete) {
complete(finallys)
}
},
...options
}
return wx.request(newOptions)
} else {
//没有任何响应拦截器则进行原始请求
return wx.request(options)
}
} catch(err) {}
}
export default Request
导入Request然后注册拦截器和baseURL,将其导出提供给外部发送请求即可
第一注意:应将request作用域顶层执行,推荐单独创建api文件夹,统一管理接口,此外注册拦截器推荐单独写个拦截器.js来注册拦截器,然后导入我们的Request.js文件周转一遍再将其导出,优雅一点,看文章第一张图即可
请不要有任何顾虑,我们编写的Request === wx.request完全成立,我们的核心是直接用wx.request并返回他,只不过在他周围切入了一些辅助功能,wx.request怎么写,怎么传参,你就怎么写 怎么传,wx.request返回什么Request就返回什么
第二注意:请不要试图省事而一气呵成,用代码举个例子
//正确写法
//设置baseURL
Request.defaults = {
baseURL: 'http://localhost:9000'
}
//错误写法
//设置baseURL
Request.defaults.baseURL = 'http://localhost:9000'
这么写调接口直接报错,为什么报错?因为我们是往一个函数注入静态属性,对象调用链会直接寻找最后一个属性baseURL,js默认你已经创建好了Request.defaults对象,实际压根没有,defaults都没有,那baseURL肯定也没有,所以直接报错baseURL未定义,注册拦截器也必须老老实实的层层结构写,这也是我们代码中用那么多try的原因,如果不用try去兜一下代码,就将变成你必须注册拦截器和baseURL,不注册就报错,try了之后你可以随心所欲,想拦截全局异常就拦截异常
第三注意:拦截器内的use函数的不强制要求返回结果,但不返回一个对象,会导致你实际的请求回调,如success拿不到response参数,因为在拦截器中无返回值,response自然也就undefined,无返回一般用于异常处理,直接将异常的过滤,二无需再每个请求中单独处理异常
比如修改和包装请求错误对象:
设置请求头携带token: