uni.addInterceptor('request', {
success(resp) {
// http状态码响应的是400-500等,也会进入成功拦截
// 如何在这里判断服务端响应异常后,阻止前端逻辑继续执行
// Promise是可以阻止的,但uni.request阻止不了
},
fail(err) {
}
})
问题已解决,拦截器中return false即可
uni.addInterceptor('request', {
success(resp) {
// http状态码响应的是400-500等,也会进入成功拦截
// 如何在这里判断服务端响应异常后,阻止前端逻辑继续执行
// Promise是可以阻止的,但uni.request阻止不了
},
fail(err) {
}
})
问题已解决,拦截器中return false即可
提供一下我的拦截器核心代码,希望对你有用
uni.addInterceptor('request', {
invoke: args => {
// 不在免校验(token)白名单且未登录则取消此次request
if (!whiteList.includes(args.url) && !token) {
return false // 返回false则会取消本次request
}
// 预设并补全参数
Object.assign(args, {
enableHttp2: true,
enableCache: true,
url: `https://xxxx.cn/${args.url}`,
header: { 'token': token },
})
},
returnValue: p => new Promise((resolve, reject) => p.then(({
statusCode,
data: { data, msg, status, ...args }
}) => {
// 我这里只有200是成功,其余状态(例如你说的400、500等)则使其进入fail()或catch()
if (statusCode !== 200) reject({ status: statusCode })
// 此处正常返回解构后的参数,在success()或then()可获取返回值
resolve(Object.assign({ status, ...data, ...args }, msg && { title: msg }))
}))
})
uni.request 类似 fetch 只有请求失败(比如跨域)才会进入 fail 回调,而业务层的失败(返回 400 ,500)并不会进 fail 回调,针对这种情况,建议基于业务需求对 uni.request 进行封装,以区分业务的成功,失败
弈凌 (作者)
明白,感谢回复。就不再包一层了,我还是在每个request中加个判断吧,如果官方能支持拦截器中返回一个Boolean值来阻断业务中的执行,就完美了。
大佬,还有一个问题,请问能一起解决了么。https://ask.dcloud.net.cn/question/164068
拦截器中处理返回值,其实是这个问题的延展:https://ask.dcloud.net.cn/question/163714
目前还是在每个request中,单独处理。我想在拦截器中统一处理下,不论是这个阻止业务执行(支持返回boolean值阻止),还是响应值的修改,都是希望技术与业务分离,该在拦截器中统一处理的就统一处理,而非每个方法都搞一遍。
2023-03-20 17:07
回复 弈凌: https://ask.dcloud.net.cn/question/164068 已回复过提供可复现的demo
https://ask.dcloud.net.cn/question/163714 该问题也已在帖子中讨论过 uni.request 的定位类似 fetch 而不是 axios
2023-03-20 17:15
弈凌 (作者)
回复 DCloud_UNI_WZF: 你好,示例demo已提供,请问这个在拦截器中阻断在页面中的request.success执行的能力,后续会考虑提供么
2023-03-20 18:28
弈凌 (作者)
回复 DCloud_UNI_WZF: 如何可以的话,还是考虑下吧,谢谢。
原因如下:
2023-03-20 18:41
弈凌 (作者)
回复 DCloud_UNI_WZF: 你好,获得后端错误响应后,拦截器中阻止success执行,只需要retruen false就可以了,可以的话,建议在文档中补充下说明
2023-03-21 12:10
弈凌 (作者)
你好,returnValue这段代码会抛出异常:Uncaught (in promise) TypeError: p.then is not a function
我尝试这样(如下),实现了终止错误请求继续执行逻辑的需求,但不确定是否有问题。
2023-03-21 11:29
弈凌 (作者)
同时还有一个需求,发现实现不了,就是在拦截器中修改响应值,比如:每个响应体中都有一个字段
id
,统一修改为_id
,类似此需求,就是修改响应体,解决这个问题:https://ask.dcloud.net.cn/question/1637142023-03-21 11:32
zZZ1Ma
回复 弈凌: vue2项目参考这里转换https://uniapp.dcloud.net.cn/api/
2023-03-21 11:32
zZZ1Ma
回复 弈凌: returnValue(args)这里的args是Promise{<pending>}吗,不是当然无法使用then()
2023-03-21 11:34
zZZ1Ma
回复 弈凌: 这里逻辑有问题,因为request调用了,你在request返回结果里再去abort()终止已经发出的请求?
2023-03-21 11:36
弈凌 (作者)
回复 2***@qq.com: 多谢解惑,这个问题已经解决了,只需要在success拦截中,return false即可阻止后续成功逻辑执行(uni.request中也不会再执行success方法)
我是vue3项目,上面的方法确实会抛出异常:Uncaught (in promise) TypeError: p.then is not a function
我梳理下,我确实有两个需求:1. 在拦截器中阻止错误响应执行 2. 在拦截器中修改响应内容
2023-03-21 11:42
zZZ1Ma
回复 弈凌: returnValue(args)=> args.then();
1:在addInterceptor外申明一个变量,记录此次请求的状态(错误or正确),returnValue内实时更改此次请求状态并赋值到该变量;然后在invoke内判断,错误则返回false取消本次请求
2:更改响应内容,我在上面的代码不是把返回的msg更改成title了?
2023-03-21 11:49
弈凌 (作者)
回复 2***@qq.com: 现在还剩下一个问题,如何在request拦截器中修改响应体,args._xhr是一个RequestTask对象
2023-03-21 11:52
zZZ1Ma
回复 弈凌: 解构对像啊
2023-03-21 11:53
弈凌 (作者)
回复 2***@qq.com: 你好,上述代码,我这边执行失败了,如果可以的话,我想提供一份示例,你帮我看下哪里有错误(有偿的)
2023-03-21 11:54
zZZ1Ma
回复 弈凌: 你加我QQ 227936048,提供一份最简单demo,一两个页面那种哦
2023-03-21 11:56
弈凌 (作者)
回复 2***@qq.com: 这个RequestTask对象中的值,需要在延迟任务setTimeout或_xhr.onprogress中才能获取到,并且不能修改,提示是只读属性。
2023-03-21 11:57
zZZ1Ma
回复 弈凌: 那就没办法,已经尽力帮助你了。你这个代码比较复杂,可否在onprogress()内解构呢?
2023-03-21 12:03
zZZ1Ma
回复 弈凌: uni.request()内不要传入callback(success / fail / complete任一个),否则returnValue内返回的是RequestTask对象
2023-03-21 12:13
弈凌 (作者)
回复 2***@qq.com: 牛批,确实是这样,问题已解决,多谢!
2023-03-21 13:13