最简单且强大的微信小程序全局请求、响应、异常拦截实现

小程序 0

前言:最近在写小程序的时候初步使用了下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: 

也许您对下面的内容还感兴趣: