原生微信小程序网络请求与上传接口封装实战指南

发布于:2025-06-24 ⋅ 阅读:(13) ⋅ 点赞:(0)

本文基于微信小程序原生 API,封装 requestuploadFile 接口,最终实现统一请求管理、请求拦截、错误处理等能力。


📦 一、为什么要封装网络请求?

微信小程序提供了 wx.requestwx.uploadFile 原生 API,但直接使用存在以下问题:

  • 重复代码多:每次都要写 header、拼接 URL、处理 loading、异常等;
  • 缺少统一错误处理:每个请求都得自己 try-catch;
  • 不好管理 token 等公共逻辑:无法统一加请求头;
  • 调试困难:没有统一日志输出或接口追踪;

封装后,我们可以统一管理所有接口请求,提升开发效率与代码可维护性。


🏗️ 二、项目结构建议

/utils
  ├── request.ts        # 通用网络请求封装
  ├── upload.ts         # 上传封装
  └── config.ts         # 环境配置

⚙️ 三、基础配置 config.ts

// utils/config.ts

export const BASE_URL = 'https://api.example.com';

export const DEFAULT_HEADER = {
  'Content-Type': 'application/json',
};

export function getToken(): string {
  // 假设从本地获取缓存 token
  return wx.getStorageSync('token') || '';
}

🌐 四、封装通用 request 请求 request.ts

// utils/request.ts

import { BASE_URL, DEFAULT_HEADER, getToken } from './config';

interface RequestOptions<T> {
  url: string;
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
  data?: any;
  header?: Record<string, string>;
  showLoading?: boolean;
  timeout?: number;
}

export function request<T = any>(options: RequestOptions<T>): Promise<T> {
  const {
    url,
    method = 'GET',
    data = {},
    header = {},
    showLoading = true,
    timeout = 10000,
  } = options;

  return new Promise((resolve, reject) => {
    if (showLoading) {
      wx.showLoading({ title: '加载中...', mask: true });
    }

    wx.request({
      url: BASE_URL + url,
      method,
      data,
      header: {
        ...DEFAULT_HEADER,
        ...header,
        Authorization: `Bearer ${getToken()}`, // 添加 token
      },
      timeout,
      success(res) {
        if (res.statusCode === 200) {
          resolve(res.data);
        } else {
          wx.showToast({ title: `错误 ${res.statusCode}`, icon: 'none' });
          reject(res);
        }
      },
      fail(err) {
        wx.showToast({ title: '网络异常', icon: 'none' });
        reject(err);
      },
      complete() {
        if (showLoading) {
          wx.hideLoading();
        }
      },
    });
  });
}

🖼️ 五、上传封装 upload.ts

// utils/upload.ts

import { BASE_URL, getToken } from './config';

export interface UploadFileOptions {
  url: string;
  filePath: string;
  name?: string;
  formData?: Record<string, string>;
  showLoading?: boolean;
}

export function uploadFile(options: UploadFileOptions): Promise<any> {
  const {
    url,
    filePath,
    name = 'file',
    formData = {},
    showLoading = true,
  } = options;

  return new Promise((resolve, reject) => {
    if (showLoading) {
      wx.showLoading({ title: '上传中...', mask: true });
    }

    wx.uploadFile({
      url: BASE_URL + url,
      filePath,
      name,
      formData,
      header: {
        Authorization: `Bearer ${getToken()}`,
      },
      success(res) {
        if (res.statusCode === 200) {
          try {
            resolve(JSON.parse(res.data)); // 注意返回是字符串
          } catch (e) {
            reject(e);
          }
        } else {
          wx.showToast({ title: '上传失败', icon: 'none' });
          reject(res);
        }
      },
      fail(err) {
        wx.showToast({ title: '上传异常', icon: 'none' });
        reject(err);
      },
      complete() {
        if (showLoading) {
          wx.hideLoading();
        }
      },
    });
  });
}

✅ 六、实际使用案例

示例:获取用户信息

// pages/user/index.ts

import { request } from '../../utils/request';

Page({
  onLoad() {
    request({
      url: '/user/info',
      method: 'GET',
    })
      .then((res) => {
        console.log('用户信息', res);
      })
      .catch(console.error);
  },
});

示例:上传头像

// pages/upload/index.ts

import { uploadFile } from '../../utils/upload';

Page({
  uploadAvatar() {
    wx.chooseImage({
      count: 1,
      success: (res) => {
        const filePath = res.tempFilePaths[0];
        uploadFile({
          url: '/upload/avatar',
          filePath,
        })
          .then((res) => {
            console.log('上传成功', res);
          })
          .catch(console.error);
      },
    });
  },
});

📚 七、总结

通过本教程,我们实现了小程序中通用的 requestuploadFile 的封装,具备了:

  • ✅ 支持 token 自动注入
  • ✅ 支持 loading 提示与关闭
  • ✅ 支持统一错误提示
  • ✅ 支持上传功能
  • ✅ 接口调用代码更清晰简洁

网站公告

今日签到

点亮在社区的每一天
去签到