手把手教你在 Taro 小程序中用 axios 替代 Taro.request:@tarojs/plugin-http 配置与拦截器封装

手把手教你在 Taro 小程序中用 axios 替代 Taro.request:@tarojs/plugin-http 配置与拦截器封装

在 Taro 开发微信小程序时,Taro.request 是官方提供的网络请求方法,但用过的同学都知道,它缺乏拦截器、Promise 链优化等实用特性。而 axios 作为前端开发者熟悉的 HTTP 库,不仅支持这些特性,还能复用我们已有的封装逻辑。不过直接在 Taro 中用 axios 会有环境适配问题,这时候 @tarojs/plugin-http 插件就能派上用场 ------ 它能让 axios 完美适配小程序环境,帮我们替代 Taro.request。

这篇文章会手把手带你完成整个流程:从项目初始化,到插件配置、axios 拦截器封装,再到实际接口调用,每一步都有具体代码和操作说明,新手也能轻松跟上。

一、为什么要替代 Taro.request?先搞懂核心优势

在开始操作前,先明确 "用 axios 替代 Taro.request" 的价值,避免为了替代而替代:

  1. 拦截器能力:axios 支持请求 / 响应拦截器,能统一处理 Token 添加、错误提示(比如 401 未登录跳转),不用在每个请求里重复写逻辑;
  1. Promise 链优化:axios 原生支持 Promise,写法更优雅,比如 axios.get().then().catch(),比 Taro.request 的回调式写法更直观;
  1. 功能更丰富:支持请求取消(防止重复点击)、请求 / 响应数据转换(比如自动解析 JSON)、超时重连等,这些 Taro.request 都需要手动封装;
  1. 复用性更强:如果你的项目同时开发 H5 和小程序,axios 封装可以跨端复用,不用为 Taro.request 单独写一套逻辑。

而 @tarojs/plugin-http 的作用,就是解决 axios 在小程序中 "水土不服" 的问题 ------ 因为 axios 底层依赖浏览器的 XMLHttpRequest,而小程序环境没有这个对象,插件会帮我们做适配,让 axios 能正常发起小程序的网络请求。

二、环境准备:从 0 搭好 Taro 项目

首先我们需要一个 Taro 项目(以 Taro 4.x + React + JavaScript 为例,其他版本流程类似),如果已有项目可以跳过这一步。

1. 安装 Taro CLI

打开终端,执行以下命令全局安装 Taro 脚手架: npm install -g @tarojs/cli

安装完成后,执行 taro -v 能看到版本号(比如 4.1.7),说明安装成功。

2. 新建 Taro 小程序项目

执行 taro init 命令创建项目,按提示选择配置:

csharp 复制代码
taro init taro-axios-demo

配置选择如下(新手建议按这个选,避免踩坑):

  • 项目名称:默认 taro-axios-demo 即可;
  • 框架:选择 React(如果用 Vue 也可以,后续代码调整对应语法即可);
  • 语言:选择 JavaScript(TS 版本后续可自行调整);
  • 微信小程序 AppID:如果没有,选 "测试号" 即可(开发阶段不影响);
  • 其他选项(是否使用 TypeScript、ESLint 等):新手建议选 "否",先聚焦核心功能。

3. 安装核心依赖

进入项目目录,安装 axios 和 @tarojs/plugin-http:

bash 复制代码
cd taro-axios-demo
npm install axios @tarojs/plugin-http --save

安装完成后,打开 package.json,能在 dependencies 里看到这两个依赖,说明安装成功:

perl 复制代码
"dependencies": {
  "axios": "^1.6.8",
  "@tarojs/plugin-http": "^3.6.32",
  // 其他依赖...
}

三、关键步骤 1:配置 @tarojs/plugin-http 插件

插件需要在 Taro 配置文件中注册,才能生效。打开项目根目录的 config/index.js,做以下修改:

1. 注册插件

在 plugins 数组中添加 @tarojs/plugin-http,表示启用这个插件:

java 复制代码
// config/index.js
module.exports = {
  projectName: "taro-axios-demo",
  date: "2025-10-13",
  designWidth: 750,
  deviceRatio: {
    640: 2.34 / 2,
    750: 1,
    828: 1.81 / 2
  },
  // 1. 注册 http 插件(关键步骤)
  plugins: [
    '@tarojs/plugin-http'  // 就是这行,不能写错
  ],
  // 其他默认配置...
};

2. 配置插件参数

在 pluginConfig 中添加 http 配置,设置接口基础路径、超时时间等全局参数(后续 axios 会用到这些配置):

java 复制代码
// config/index.js(接上面的代码)
module.exports = {
  // 前面的配置...
  // 2. 配置 http 插件参数(关键步骤)
  pluginConfig: {
    http: {
      baseURL: '域名',  // 你的接口基础域名
      timeout: 10000,  // 请求超时时间(单位:毫秒)
      headers: {
        'Content-Type': 'application/json'  // 默认请求头(JSON 格式)
      }
    }
  },
  // 后面的配置(framework、compiler 等)...
};

这里的 baseURL 很重要 ------ 后续我们写接口路径时,不用再写完整域名,比如接口 baidu.com/api/list,只需写 /api/list 即可,axios 会自动拼接 baseURL。

四、关键步骤 2:封装 axios 拦截器(核心中的核心)

这一步是 "替代 Taro.request" 的核心 ------ 我们要封装 axios 的请求 / 响应拦截器,统一处理 Token、错误提示等逻辑,避免在每个请求里重复写代码。

在 src 目录下新建 utils 文件夹,再在里面新建 request.js 文件(这个文件就是我们的 axios 封装工具):

1. 基础结构:创建 axios 实例

首先导入 axios 和 Taro,然后根据插件配置创建 axios 实例:

javascript 复制代码
// src/utils/request.js
import axios from 'axios';
import Taro from '@tarojs/taro';
// 1. 创建 axios 实例(使用插件配置的参数)
const service = axios.create({
  baseURL: '你的域名',  // 和 pluginConfig.http 保持一致
  timeout: 10000,  // 超时时间(和插件配置一致)
  headers: {
    'Content-Type': 'application/json'  // 默认请求头
  }
});

这里为什么不直接用插件配置的参数,而是重新写一遍?因为 Taro 4.x 移除了 getPluginConfig 方法,直接读取插件配置会报错,所以我们手动保持一致即可(后续如果要改,只需改这里和 config/index.js 两处)。

2. 请求拦截器:统一添加 Token

请求拦截器的作用是 ------ 在请求发出去之前,做一些统一处理,比如添加 Token(登录态)。大部分接口都需要 Token 验证,这里我们从 Taro 缓存中获取 Token,添加到请求头:

javascript 复制代码
// src/utils/request.js(接上面的代码)
// 2. 请求拦截器:添加 Token、处理请求参数
service.interceptors.request.use(
  (config) => {
    // 从 Taro 缓存中获取 Token(登录后会存入缓存)
    const token = Taro.getStorageSync('userToken');
    // 如果有 Token,添加到请求头(格式按你的接口要求来,这里是 Bearer Token)
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;  // 返回处理后的配置
  },
  (error) => {
    // 请求出错时的处理(比如参数错误)
    console.error('请求拦截器错误:', error);
    // 提示用户
    Taro.showToast({
      title: '请求参数错误',
      icon: 'none',  // 不显示图标
      duration: 2000  // 提示时长(毫秒)
    });
    return Promise.reject(error);  // 把错误抛出去,方便后续处理
  }
);

3. 响应拦截器:统一处理错误和数据

响应拦截器的作用是 ------ 在拿到接口返回数据后,做一些统一处理,比如:

  • 如果接口返回错误(比如 401 未登录、403 无权限),统一提示用户;
  • 如果接口返回成功,直接提取核心数据(过滤外层的 success、code 等字段)。

继续在 request.js 中添加响应拦截器:

javascript 复制代码
// src/utils/request.js(接上面的代码)
// 3. 响应拦截器:统一处理错误、提取数据
service.interceptors.response.use(
  (response) => {
    // 接口返回的原始数据(response.data 是接口返回的 JSON)
    const res = response.data;
    // 假设你的接口返回格式是:{ success: boolean, data: any, code: number, message: string }
    // 如果 success 是 true,说明请求成功,返回核心数据(res.data)
    if (res.success) {
      return res.data;  // 后续调用接口时,拿到的就是这个 data
    } else {
      // 如果 success 是 false,说明业务错误(比如参数错误、权限不足)
      handleBusinessError(res.code, res.message);  // 专门的错误处理函数
      return Promise.reject(res);  // 抛错,让后续的 catch 能捕获到
    }
  },
  (error) => {
    // 网络错误(比如超时、断网、域名错误)
    console.error('响应拦截器错误:', error);
    // 判断错误类型(超时还是其他)
    const errorMsg = error.message?.includes('timeout') 
      ? '请求超时,请稍后重试' 
      : '网络异常,请检查网络';
    // 提示用户
    Taro.showToast({
      title: errorMsg,
      icon: 'none',
      duration: 2000
    });
    return Promise.reject(error);  // 抛错,方便后续处理
  }
);

4. 封装业务错误处理函数

上面用到了 handleBusinessError 函数,专门处理接口返回的业务错误(比如 401 未登录),我们在响应拦截器下面定义这个函数:

php 复制代码
// src/utils/request.js(接上面的代码)
// 4. 业务错误处理函数(根据你的接口错误码调整)
const handleBusinessError = (code, message) => {
  switch (code) {
    case 400003:  // 假设 400003 是"未登录"的错误码
      Taro.showToast({
        title: message || '请先登录',
        icon: 'none',
        duration: 2000
      });
      // 跳转到登录页(登录后可以返回当前页,这里简化处理)
      Taro.navigateTo({
        url: '/pages/login/index'  // 你的登录页路径
      });
      break;
    case 403:  // 假设 403 是"无权限"的错误码
      Taro.showToast({
        title: message || '你没有操作权限',
        icon: 'none',
        duration: 2000
      });
      break;
    default:  // 其他错误
      Taro.showToast({
        title: message || '操作失败',
        icon: 'none',
        duration: 2000
      });
      break;
  }
};

这里的错误码(比如 400003、403)需要根据你的实际接口文档调整,不要直接抄我的!

5. 封装 get/post 方法(方便调用)

最后,我们封装 get 和 post 方法,让后续调用接口时更简洁:

javascript 复制代码
// src/utils/request.js(接上面的代码)
// 5. 封装 get/post 方法(对外暴露)
export default {
  // get 请求:params 是 URL 参数(比如 ?id=1&name=test)
  get(url, params = {}, config = {}) {
    return service.get(url, { params, ...config });
  },
  // post 请求:data 是请求体参数(JSON 格式)
  post(url, data = {}, config = {}) {
    return service.post(url, data, config);
  }
};

这样,后续我们调用接口时,只需写 request.get('/api/xxx') 或 request.post('/api/xxx', data) 即可,非常简洁。

五、关键步骤 3:调用接口(实战演示)

封装好 axios 后,我们来实战调用一个接口(你项目中的接口) ------ 例如: baiodu.com/api/list(获取用户权限)为例,演示如何在页面中使用。

1. 按业务模块封装接口(推荐做法)

在 src 目录下新建 api 文件夹,再新建 account.js 文件(按业务模块分文件,比如 account 对应账号相关接口),里面定义我们的接口函数:

javascript 复制代码
// src/api/account.js
// 导入封装好的 axios 工具
import request from '../utils/request';
/**
 * 获取用户权限列表接口
 * 完整地址:baseURL + /api/list
 * @returns {Promise} 权限列表数据
 */
export const getPermissions = () => {
  // 调用 get 方法(因为这个接口是 GET 类型)
  return request.get('/api/account/getPermissions');
};
// 如果你有其他账号相关接口,也可以在这里添加,比如登录接口:
// export const login = (data) => {
//   return request.post('/api/account/login', data);
// };

2. 在页面中调用接口

以首页(src/pages/index/index.jsx)为例,我们在页面加载时调用 getPermissions 接口,获取权限列表并展示:

第一步:页面代码结构
javascript 复制代码
// src/pages/index/index.jsx
import React, { useState, useEffect } from 'react';
import { View, Text, Button, ScrollView } from '@tarojs/components';
import Taro from '@tarojs/taro';
// 导入接口函数
import { getPermissions } from '../../api/account';
// 导入样式(后面会写)
import './index.scss';
export default function Index() {
  // 状态管理:权限列表、加载状态
  const [permissions, setPermissions] = useState([]);
  const [loading, setLoading] = useState(false);
  // 页面加载时调用接口( useEffect 模拟生命周期)
  useEffect(() => {
    fetchPermissions();
  }, []);
  // 调用接口的函数(async/await 写法,更直观)
  const fetchPermissions = async () => {
    try {
      // 开始加载:设置 loading 为 true
      setLoading(true);
      // 调用接口(这里拿到的是响应拦截器处理后的核心数据)
      const data = await getPermissions();
      // 接口成功:更新权限列表状态
      setPermissions(data || []);
      // 提示用户成功
      Taro.showToast({
        title: '获取权限成功',
        icon: 'success',  // 显示成功图标
        duration: 1500
      });
    } catch (error) {
      // 接口失败:重置权限列表(错误提示在响应拦截器已经处理了)
      setPermissions([]);
      console.error('获取权限失败:', error);
    } finally {
      // 结束加载:不管成功还是失败,都设置 loading 为 false
      setLoading(false);
    }
  };
  // 页面渲染
  return (
    <View className="index-container">
      <Text className="page-title">用户权限列表</Text>
      {/* 刷新按钮(可以重新调用接口) */}
      <Button 
        className="refresh-btn" 
        loading={loading}  // 加载时显示loading状态
        onClick={fetchPermissions}  // 点击重新调用接口
      >
        {loading ? '加载中...' : '刷新权限'}
     </doubaocanvas>

六、完整项目参考

gitee.com/lishuo18/ta...

相关推荐
我不爱你了4 小时前
用 Python + Vue3 打造超炫酷音乐播放器:网易云歌单爬取 + Three.js 波形可视化
前端
Joyee6914 小时前
React native 设计初衷
前端
重生之我是菜鸡程序员4 小时前
uniapp 顶部通知 上滑隐藏
前端·javascript·uni-app
PCC4 小时前
语音控制的太空射击游戏开发笔记
前端
FliPPeDround4 小时前
告别 uni-app 启动烦恼:@uni-helper/unh 让开发流程更顺畅
前端·微信小程序·uni-app
东华帝君5 小时前
ref 和 reactive的区别
前端
joykit5 小时前
threejs 四元数
前端
Joyee6915 小时前
RN 的初版架构——通信机制
前端·react native
Swift社区5 小时前
从 0 到 1 构建一个完整的 AGUI 前端项目的流程在 ESP32 上运行
前端·算法·职场和发展