无所不能的uniapp拦截器-uni.addInterceptor
拦截器能做什么?
uni.addInterceptor
是 uni-app
框架中的一个 API,用于为特定的异步 API 方法添加拦截器。拦截器可以在方法执行前或执行后插入自定义逻辑,比如权限校验、日志记录、数据预处理等。 附上官方文档链接
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
invoke | Function | 否 | 拦截前触发 | ||
returnValue | Function | 否 | 方法调用后触发,处理返回值 | ||
success | Function | 否 | 成功回调拦截 | ||
fail | Function | 否 | 失败回调拦截 | ||
complete | Function | 否 | 完成回调拦截 |
项目实战
uni.request
拦截器- 登录校验拦截器
uni.setStorage
数据预处理- 隐私权限判断、引导
uni.request
拦截器
ts
const BASE_URL = 'https://www.example.com/'
const httpInterceptor: UniNamespace.InterceptorOptions = {
invoke(args) {
// request 触发前拼接 url
args.url = BASE_URL + args.url
},
success(result) {
console.log('interceptor-success',result)
// 请求成功,但接口报错等情况上报
if(result.data.code === xxx){
errorReport(result.data.msg)
}
},
fail(err) {
console.log('interceptor-fail',err)
// 请求失败等情况上报
errorReport()
},
complete(res) {
console.log('interceptor-complete',res)
}
}
// 进行错误上报
function errorReport(errMsg?: string){
uni.showToast({
icon: "none",
title: errMsg || "网络错误,换个网络试试",
});
customReport({
msg: 'xxxx'
})
}
ts
export const requestInterceptor = {
install() {
// 拦截 request 请求
uni.addInterceptor("request", httpInterceptor);
// 拦截 uploadFile 文件上传
uni.addInterceptor("uploadFile", httpInterceptor);
},
};
登录校验拦截器
ts
const loginRoute = "/pages/login/index";
let needLoginPages: string[] = [
"/pages/order/index",
];
/**
* 判断是否登录
*/
export function isLogged(): boolean {
return false;
}
// 黑名单登录拦截器 - (适用于大部分页面不需要登录,少部分页面需要登录)
const navigateToInterceptor: UniNamespace.InterceptorOptions = {
// 注意,这里的url是 '/' 开头的,如 '/pages/index/index',跟 'pages.json' 里面的 path 不同
invoke({ url }: { url: string }) {
// console.log(url)
const path = url.split("?")[0];
const isNeedLogin = needLoginPages.includes(path);
if (!isNeedLogin) {
return true;
}
const hasLogin = isLogged();
if (hasLogin) {
return true;
}
goLogin(url);
return false;
},
};
function goLogin(redirect: string = "") {
uni.navigateTo({
url: `${loginRoute}?redirect=${encodeURIComponent(redirect)}`,
});
}
export const routeInterceptor = {
install() {
uni.addInterceptor("navigateTo", navigateToInterceptor);
uni.addInterceptor("reLaunch", navigateToInterceptor);
uni.addInterceptor("redirectTo", navigateToInterceptor);
uni.addInterceptor("switchTab", navigateToInterceptor);
},
};
uni.setStorage
数据预处理
ts
// 这是个数据处理函数
function processingData(){
}
const storage: UniNamespace.InterceptorOptions = {
invoke(args) {
console.log('存储数据前:', args);
args.data = processingData(args.data);
console.log('处理后的数据:', args.data);
},
success() {
console.log('数据存储成功');
},
fail(err) {
console.error('数据存储失败:', err);
}
}
ts
export const storageInterceptor = {
install() {
uni.addInterceptor("setStorage", storage);
},
};
借助拦截器修复快手小程序平台的一个bug
- bug背景:
ks.setStorage
不支持储存proxy
对象,会报错 - 相关链接:github.com/dcloudio/un...
ts
const setStorageInterceptor: UniNamespace.InterceptorOptions = {
invoke(args: { data: any }) {
// console.log(args, "========args=======");
// #ifdef MP-KUAISHOU
args.data = JSON.parse(JSON.stringify(args.data));
// #endif
},
success(args) {
// console.log(args, "========success=======");
},
fail(err) {
// console.log(err, "========fail=======");
},
};
/**
* 解决快手小程序setStorage不支持proxy对象的问题
* */
export const KuaiShouSetStorageProxyFixInterceptor = {
install() {
// 拦截 setStorage
uni.addInterceptor("setStorage", setStorageInterceptor);
},
};
隐私权限判断、引导
开发中......