《UniApp - uni.request 请求二次封装》

        在 UniApp 中,使用 uni.request 进行网络请求是常见的操作。为了简化请求流程,统一错误处理和响应处理,我们通常会对 uni.request 进行二次封装。二次封装后,你可以在项目中通过调用自定义的请求方法,而不必每次都手动写重复的请求配置。

本文将介绍如何创建一个通用的请求封装工具。

一、封装文件结构

我们将封装的请求方法放在一个单独的文件中,便于维护和复用。通常,这个文件可以放在 utils/request.js 路径下。

/src
  ├── /utils
       └── request.js  // 网络请求二次封装

二、封装 uni.request

2.1 基本封装

首先,我们定义一个封装的 request 函数,处理请求、响应以及错误捕获。

// /src/utils/request.js

const BASE_URL = 'https://api.example.com';  // 接口基础 URL
const TIMEOUT = 10000;  // 请求超时时间(毫秒)

// 请求方法封装
const request = (options) => {
  // 统一处理请求头
  let headers = {
    'Content-Type': 'application/json', // 默认请求内容类型
    ...options.headers,  // 允许传入额外的请求头
  };

  // 如果有 token,则添加到请求头
  const token = uni.getStorageSync('token');
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }

  return new Promise((resolve, reject) => {
    uni.request({
      url: BASE_URL + options.url,  // 拼接基础 URL 和接口路径
      method: options.method || 'GET',  // 默认为 GET 请求
      data: options.data || {},
      header: headers,
      timeout: options.timeout || TIMEOUT,  // 请求超时时间
      success: (res) => {
        if (res.statusCode === 200) {
          // 请求成功,处理返回数据
          resolve(res.data);
        } else {
          // 请求失败,处理错误
          reject(res);
        }
      },
      fail: (err) => {
        // 网络或服务器错误,统一处理
        reject(err);
      },
    });
  });
};

export default request;

2.2 请求参数说明

  • url: 请求接口的路径,必须传入。
  • method: 请求方法,默认为 GET,也可以传 POSTPUT 等。
  • data: 请求的参数,可以是一个对象,传递给服务器。
  • headers: 可选的请求头,允许用户传递自定义请求头。
  • timeout: 请求超时设置,默认为 10 秒。

三、使用封装的请求方法

3.1 发送请求

在页面或其他业务逻辑中使用二次封装的 request 方法来发送请求。通过 thencatch 处理成功和失败的响应。

// 示例:调用封装的请求方法进行 API 请求

import request from '@/utils/request';  // 引入请求工具

export default {
  data() {
    return {
      userInfo: null,
    };
  },
  methods: {
    // 获取用户信息接口
    getUserInfo() {
      request({
        url: '/user/info',  // 接口路径
        method: 'GET',  // 请求方法
      })
        .then((res) => {
          // 成功回调,处理返回数据
          this.userInfo = res.data;
        })
        .catch((err) => {
          // 失败回调,统一错误处理
          uni.showToast({
            title: '请求失败',
            icon: 'none',
          });
        });
    },
  },
  mounted() {
    this.getUserInfo();
  },
};

四、添加全局请求拦截

如果你需要在每次请求前进行一些额外的操作(例如显示加载动画、请求权限等),可以在封装的 request 函数中加入拦截器。

4.1 请求前操作

在请求发送前,我们可以加一个请求的 loading 提示,通知用户正在加载数据。

const request = (options) => {
  // 统一处理请求头
  let headers = {
    'Content-Type': 'application/json',
    ...options.headers,
  };

  const token = uni.getStorageSync('token');
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }

  // 显示加载动画
  uni.showLoading({
    title: '加载中...',
    mask: true,  // 遮罩层,防止用户操作
  });

  return new Promise((resolve, reject) => {
    uni.request({
      url: BASE_URL + options.url,
      method: options.method || 'GET',
      data: options.data || {},
      header: headers,
      timeout: options.timeout || TIMEOUT,
      success: (res) => {
        uni.hideLoading();  // 请求完成,隐藏加载动画
        if (res.statusCode === 200) {
          resolve(res.data);
        } else {
          reject(res);
        }
      },
      fail: (err) => {
        uni.hideLoading();  // 请求失败,隐藏加载动画
        reject(err);
      },
    });
  });
};

五、统一处理错误和提示

你可以在二次封装中统一处理错误信息,确保用户得到清晰的提示。

5.1 错误处理

request.js 中可以对不同的错误进行处理,例如网络错误、超时错误等。

const request = (options) => {
  // 请求头处理
  let headers = {
    'Content-Type': 'application/json',
    ...options.headers,
  };

  const token = uni.getStorageSync('token');
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }

  return new Promise((resolve, reject) => {
    uni.request({
      url: BASE_URL + options.url,
      method: options.method || 'GET',
      data: options.data || {},
      header: headers,
      timeout: options.timeout || TIMEOUT,
      success: (res) => {
        if (res.statusCode === 200) {
          resolve(res.data);
        } else {
          // 根据错误状态码处理
          uni.showToast({
            title: res.data.message || '请求失败',
            icon: 'none',
          });
          reject(res);
        }
      },
      fail: (err) => {
        uni.showToast({
          title: '网络请求失败',
          icon: 'none',
        });
        reject(err);
      },
    });
  });
};

六、总结

通过对 uni.request 的二次封装,我们可以统一处理请求头、参数、超时、错误提示等,使得请求代码更加简洁和规范。二次封装不仅能提高代码复用性,还能帮助你集中管理请求逻辑,提高维护性。

注意事项

  • 错误处理:务必统一错误提示,避免多个页面重复编写错误处理逻辑。
  • 权限管理:对于需要登录的接口,统一管理 token 的处理,确保每次请求都带上有效的 token。

希望这篇文章能帮助大家更好地封装 UniApp 中的请求,提升开发效率