Taro-04-网络请求

一、Taro 为什么不直接用 fetch/axios,而是封装了一层跨端 API

同一套代码要运行在:

  • 微信小程序
  • H5
  • React Native
  • 支付宝小程序
  • 抖音小程序

所以 Taro 提供统一 API:

复制代码
Taro.request()

底层自动适配:

复制代码
// H5
window.fetch / XMLHttpRequest

// 微信小程序
wx.request

// 支付宝小程序
my.request
二、请求/响应拦截器(同一拦截器里写)

Taro 用的是洋葱模型:一个拦截器函数里,既可以在发请求前改参数,也可以在 chain.proceed() 返回的 Promise 上处理响应。

TypeScript 复制代码
Taro.addInterceptor(chain => {
  const { requestParams } = chain;
  const { url } = requestParams;

  // 请求发出前
  return chain.proceed({
    ...requestParams,
    header: {
      ...requestParams.header,
      Authorization: getToken(),
    },
  }).then(res => {
    // 响应回来后
    if (res.statusCode === 401) {
      // 跳转登录等
    }
    if (res.data?.code !== 0) {
      Taro.showToast({ title: res.data?.message ?? '请求失败', icon: 'none' });
      return Promise.reject(res);
    }
    return res;
  });
});
三、企业项目

通常封装:

1、网络请求基础地址
TypeScript 复制代码
const serverUrl = process.env.NODE_ENV === 'development' ? '/proxy' : '';
2、错误管理器
TypeScript 复制代码
const errorMessageManager = {
  messages: new Map<string, number>(),
  timeout: 3000,
  showErrorOnce(key: string, msg: string) {
    const now = Date.now();
    const lastShown = this.messages.get(key);
    if (!lastShown || now - lastShown > this.timeout) {
      Taro.showToast({ title: msg, icon: 'none', duration: 2000 });
      this.messages.set(key, now);
    }
  },
};
3、ts类型定义
TypeScript 复制代码
type RequestConfig = Taro.request.Option & {
  ignoreError?: boolean;
  params?: Record<string, unknown>;
};
// 定义一个新类型 HttpExtraConfig,它等于 RequestConfig 去掉 url、method、data 这三个属性之后剩下的部分。
// 2. Omit<T, K>
// TypeScript 内置工具类型,含义是:

// Omit<某个类型, 要排除的键>
// 第一个参数 T:源类型
// 第二个参数 K:要从 T 里排除的属性名
type HttpExtraConfig = Omit<RequestConfig, 'url' | 'method' | 'data'>;
4、封装请求前的处理(类似于axios的请求拦截)
TypeScript 复制代码
function patchRequestParams(params: Taro.request.Option): Taro.request.Option {
  return {
    ...params,
    url: `${serverUrl}${params.url}`,
    header: {
      ...params.header,
      Authorization: getToken(),
    },
  };
}
5、封装响应后的处理(响应拦截)
TypeScript 复制代码
function handleResponse(
  res: Taro.request.SuccessCallbackResult,
  params: Taro.request.Option & { ignoreError?: boolean },
) {
  const { statusCode } = res;
  const ignoreError = (params as any).ignoreError;
  if (statusCode === 401) {
    errorMessageManager.showErrorOnce('auth-401', '登录过期,请重新登录!');
    setTimeout(() => Taro.reLaunch({ url: '/pages/login/index' }), 500);
    throw res;
  }
  if (!ignoreError && (statusCode === 400 || statusCode >= 500)) {
    const msg = (res.data as { message?: string })?.message || '请求失败';
    errorMessageManager.showErrorOnce(`error-${statusCode}`, msg);
    throw res;
  }
  return res;
}
6、注册全局拦截器(需在 app 启动时调用一次)
TypeScript 复制代码
export function setupRequestInterceptors() {
  Taro.addInterceptor((chain) => {
    const params = patchRequestParams(chain.requestParams);
    return chain.proceed(params).then((res) => handleResponse(res, params));
  });
}
7、封装 get 请求
TypeScript 复制代码
export const get = (url: string, params = {}, config: HttpExtraConfig = {}) =>
  Taro.request({
    ...config,
    url,
    method: 'GET',
    data: params,
  }).then((res) => (config.responseType ? res : res.data));
8、封装 post 请求
TypeScript 复制代码
export const post = (
  url: string,
  data?: unknown,
  config: HttpExtraConfig = {},
) =>
  Taro.request({
    ...config,
    url,
    method: 'POST',
    data,
  }).then((res) => (config.responseType ? res : res.data));
9、封装 put 请求
TypeScript 复制代码
export const put = (
  url: string,
  data?: unknown,
  config: HttpExtraConfig = {},
) =>
  Taro.request({
    ...config,
    url,
    method: 'PUT',
    data,
  }).then((res) => res.data);
10、封装 del 请求
TypeScript 复制代码
export const del = (url: string, params = {}, config: HttpExtraConfig = {}) =>
  Taro.request({
    ...config,
    url,
    method: 'DELETE',
    data: params,
  }).then((res) => res.data);
相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄2 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端