uniapp拦截器应用场景实例(请求拦截、登录校验和数据预处理等)

前端 潘老师 1周前 (04-14) 23 ℃ (0) 扫码查看

uniapp中的uni.addInterceptor是个非常实用的API,可以给特定的异步API方法添加拦截器,通过在方法执行前后插入自定义逻辑,实现权限校验、日志记录、数据预处理等功能。接下来,我们详细了解下它的具体用法和在实际项目中的应用。下面先附上官方文档链接,方便大家查阅更详细的信息。

uni.addInterceptor有多个参数,每个参数都有不同的作用:

  • invoke:类型为Function,非必填项。它会在拦截前触发,可用于在异步API方法执行前对参数进行处理。
  • returnValue:同样是Function类型,非必填。在方法调用后触发,主要用于处理返回值。
  • success:Function类型,非必填。这是成功回调拦截,当异步API方法执行成功时会被调用。
  • fail:Function类型,非必填。用于失败回调拦截,在异步API方法执行失败时触发。
  • complete:Function类型,非必填。完成回调拦截,无论异步API方法执行成功与否,都会在最后调用它。

一、项目实战应用

(一)uni.request拦截器

在实际开发中,uni.request用于发起网络请求,通过拦截器可以对请求和响应进行统一处理。比如,我们可以设置一个基础URL,在每次请求前自动拼接完整的URL,同时对请求结果进行错误上报。

const BASE_URL = 'https://www.example.com/'

const httpInterceptor: UniNamespace.InterceptorOptions = {
  // 在request触发前,拼接完整的URL
  invoke(args) {
    args.url = BASE_URL + args.url
  },
  // 处理请求成功的情况,如果接口返回的data中code符合特定值,进行错误上报
  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'
    })
}

为了方便使用这个拦截器,我们可以把它封装起来:

export const requestInterceptor = {
  install() {
    // 对request请求进行拦截
    uni.addInterceptor("request", httpInterceptor);
    // 对uploadFile文件上传操作也进行同样的拦截处理
    uni.addInterceptor("uploadFile", httpInterceptor);
  },
};

在这段代码里,invoke函数负责拼接URL,successfail函数分别处理请求成功和失败时的错误上报,complete函数用于记录请求完成的信息。通过requestInterceptor.install()调用,就能对requestuploadFile操作生效。

(二)登录校验拦截器

在很多应用中,部分页面需要用户登录后才能访问。这时,我们可以利用拦截器来实现登录校验。

const loginRoute = "/pages/login/index";
// 定义需要登录才能访问的页面数组
let needLoginPages: string[] = [
 "/pages/order/index",
];
// 判断用户是否登录的函数,这里返回false只是示例,实际需要根据业务逻辑实现
export function isLogged(): boolean {
 return false;
}
// 黑名单登录拦截器,适用于大部分页面不需要登录,少部分页面需要登录的场景
const navigateToInterceptor: UniNamespace.InterceptorOptions = {
 // 这里的url是 '/' 开头的,如 '/pages/index/index',与 'pages.json' 里面的path不同
 invoke({ url }: { url: string }) {
   // 提取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;
 },
};
// 跳转到登录页面的函数,同时带上当前页面的url作为参数,方便登录后返回
function goLogin(redirect: string = "") {
 uni.navigateTo({
   url: `${loginRoute}?redirect=${encodeURIComponent(redirect)}`,
 });
}
export const routeInterceptor = {
  install() {
   // 对navigateTo、reLaunch、redirectTo、switchTab等页面跳转方法进行拦截
   uni.addInterceptor("navigateTo", navigateToInterceptor);
   uni.addInterceptor("reLaunch", navigateToInterceptor);
   uni.addInterceptor("redirectTo", navigateToInterceptor);
   uni.addInterceptor("switchTab", navigateToInterceptor);
 },
};

在这个登录校验拦截器中,invoke函数会在页面跳转前被调用。它先判断目标页面是否需要登录,如果需要,再检查用户是否已登录。若用户未登录,就跳转到登录页面,并把当前页面的URL作为参数传递过去,以便登录成功后能返回原页面。

(三)uni.setStorage数据预处理

在使用uni.setStorage存储数据时,有时需要对数据进行预处理。比如下面这个例子:

// 这是个数据处理函数,具体逻辑根据实际需求编写
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);
  }
}

同样,我们可以把这个拦截器封装起来,方便使用:

export const storageInterceptor = {
  install() {
    uni.addInterceptor("setStorage", storage);
  },
};

在这个拦截器中,invoke函数在数据存储前对args.data进行处理,successfail函数分别处理存储成功和失败的情况。

(四)借助拦截器修复快手小程序平台的一个bug

在快手小程序开发中,ks.setStorage存在不支持储存proxy对象的问题,会导致报错。我们可以利用拦截器来解决这个问题。

const setStorageInterceptor: UniNamespace.InterceptorOptions = {
  // 在快手小程序平台下,将数据转换为JSON字符串再解析,避免存储proxy对象报错
  invoke(args: { data: any }) {
    // #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);
  },
};

在这段代码中,invoke函数里通过#ifdef MP-KUAISHOU条件判断,只有在快手小程序平台下才会对数据进行处理,将数据转换为JSON字符串再解析,从而避免存储proxy对象时报错。

通过上述这些实例可以看出,uniapp的拦截器功能非常强大,在项目开发中合理运用它,能够提高代码的复用性和可维护性,大家一定要用起来。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/front/17205.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】