前言:最近在写小程序的时候初步使用了下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就返回什么
第二注意:请不要试图省事而一气呵成,用代码举个例子
//正确写法//设置baseURLRequest.defaults = { baseURL: 'http://localhost:9000'}//错误写法//设置baseURLRequest.defaults.baseURL = 'http://localhost:9000'
这么写调接口直接报错,为什么报错?因为我们是往一个函数注入静态属性,对象调用链会直接寻找最后一个属性baseURL,js默认你已经创建好了Request.defaults对象,实际压根没有,defaults都没有,那baseURL肯定也没有,所以直接报错baseURL未定义,注册拦截器也必须老老实实的层层结构写,这也是我们代码中用那么多try的原因,如果不用try去兜一下代码,就将变成你必须注册拦截器和baseURL,不注册就报错,try了之后你可以随心所欲,想拦截全局异常就拦截异常
第三注意:拦截器内的use函数的不强制要求返回结果,但不返回一个对象,会导致你实际的请求回调,如success拿不到response参数,因为在拦截器中无返回值,response自然也就undefined,无返回一般用于异常处理,直接将异常的过滤,二无需再每个请求中单独处理异常
比如修改和包装请求错误对象:
设置请求头携带token: