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

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值