Umijs项目中的请求封装


项目依赖

  • "umi": "^3.5.35",

文件配置

在 src/app.js 文件中写入以下代码

// 导入依赖
import httpErrorMessage from "@/network/httpErrorMessage.js"; // 处理请求异常的文字集合
import codeErrorMessage from "@/network/codeErrorMessage.js"; // 处理根据自身业务定义的请求异常的文字集合
import urlsWithoutToken from "@/network/urlsWithoutToken.js"; // 不需要携带token URL集合

// 请求封装
const lang = "zh-CN"; // zh-CN | en-US
// 服务器请求错误状态处理
const errorHandler = (error) => {
  const { response } = error;
  if (response && response.status) {
    const errorText =
      httpErrorMessage[lang][response.status] || response.statusText;
    message.error(errorText);
  }
  return response;
};
export const request = {
  errorHandler,
  requestInterceptors: [
    // 请求拦截器,接收数组,可设置多个拦截器
    (_, options) => {
      const shouldIncludeToken = !urlsWithoutToken.includes(options.url); // 判断是否需要携带token
      const modifiedOptions = {
        ...options,
        data: {
          ...(options?.data ?? {}),
        }, // 可在这里对数据中统一处理
        headers: {
          ...(options?.headers ?? {}),
          ...(shouldIncludeToken && {
            Authorization: `Bearer ${localStorage.getItem("ACCESS_TOKEN")}`, // 携带token
          }),
        },
      };
      return { ...modifiedOptions, url: `/dev${options.url}` }; // 修改URL只能走这样的方法
    },
  ],
  responseInterceptors: [
    // 相应拦截器,也接受数组
    async (response) => {
      if (response) {
        if (response.status === 401) {
          // token过期的时候自动刷新获取新的token自动登录,当然这是根据自己页面的需求决定,大多都是token过期跳转登录页面,重新登陆
          localStorage.clear("ACCESS_TOKEN");
          localStorage.clear("USERNAME");
          history.push("/login");
        }
        if (response.status === 200) {
          // 后端规定了一些自定义返回的errorCode码,返回后端的自定义提示信息
          const data = await response.clone().json();
          if (data && data.messageCode) {
            const errorText =
              codeErrorMessage[lang][data.messageCode] ||
              codeErrorMessage[lang][10000]; //  codeErrorMessage支持多语言环境的json文件,和httpErrorMessage 一样写法
            // debugger
            message.error(errorText);
          }
          if (data && data.code === 200 && !!data.data) {
            // 后端返回200但数据为空的情况
            return data;
          }
        }
      } else {
        message.error(
          lang == "zh-CN"
            ? "您的网络发生异常,无法连接服务器"
            : "Your network is abnormal and you cannot connect to the server"
        );
      }
      return response;
    },
  ],
};

httpErrorMessage.js

const httpErrorMessage = {
  "en-US": {
    200: "The server successfully returned the requested data.",
    201: "Data is created or modified successfully. Procedure",
    202: "A request has been queued in the background (asynchronous task).",
    204: "Succeeded in deleting data. Procedure",
    400: "The server did not create or modify data.",
    401: "User does not have permission (wrong token, username, password).",
    403: "The user is authorized, but access is prohibited.",
    404: "The request was made for a nonexistent record, and the server did not act on it.",
    406: "The requested format is not available.",
    410: "The requested resource is permanently deleted and will not be retrieved.",
    422: "A validation error occurred while creating an object.",
    500: "An error occurred on the server. Check the server.",
    502: "Gateway error.",
    503: "The service is unavailable, the server is temporarily overloaded or maintained.",
    504: "The gateway timed out.",
  },
  "zh-CN": {
    200: "服务器成功返回请求的数据。",
    201: "新建或修改数据成功。",
    202: "一个请求已经进入后台排队(异步任务)。",
    204: "删除数据成功。",
    400: "发出的请求有错误,服务器没有进行新建或修改数据的操作。",
    401: "用户没有权限(令牌、用户名、密码错误)。",
    403: "用户得到授权,但是访问是被禁止的。",
    404: "发出的请求针对的是不存在的记录,服务器没有进行操作。",
    406: "请求的格式不可得。",
    410: "请求的资源被永久删除,且不会再得到的。",
    422: "当创建一个对象时,发生一个验证错误。",
    500: "服务器发生错误,请检查服务器。",
    502: "网关错误。",
    503: "服务不可用,服务器暂时过载或维护。",
    504: "网关超时。",
  },
};
export default httpErrorMessage;

codeErrorMessage.js 这里我没有做什么自定义(因为自身业务不需要)

const codeErrorMessage = {
  "en-US": {
    200: "The server successfully returned the requested data.",
    201: "Data is created or modified successfully. Procedure",
    202: "A request has been queued in the background (asynchronous task).",
    204: "Succeeded in deleting data. Procedure",
    400: "The server did not create or modify data.",
    401: "User does not have permission (wrong token, username, password).",
    403: "The user is authorized, but access is prohibited.",
    404: "The request was made for a nonexistent record, and the server did not act on it.",
    406: "The requested format is not available.",
    410: "The requested resource is permanently deleted and will not be retrieved.",
    422: "A validation error occurred while creating an object.",
    500: "An error occurred on the server. Check the server.",
    502: "Gateway error.",
    503: "The service is unavailable, the server is temporarily overloaded or maintained.",
    504: "The gateway timed out.",
  },
  "zh-CN": {
    200: "服务器成功返回请求的数据。",
    201: "新建或修改数据成功。",
    202: "一个请求已经进入后台排队(异步任务)。",
    204: "删除数据成功。",
    400: "发出的请求有错误,服务器没有进行新建或修改数据的操作。",
    401: "用户没有权限(令牌、用户名、密码错误)。",
    403: "用户得到授权,但是访问是被禁止的。",
    404: "发出的请求针对的是不存在的记录,服务器没有进行操作。",
    406: "请求的格式不可得。",
    410: "请求的资源被永久删除,且不会再得到的。",
    422: "当创建一个对象时,发生一个验证错误。",
    500: "服务器发生错误,请检查服务器。",
    502: "网关错误。",
    503: "服务不可用,服务器暂时过载或维护。",
    504: "网关超时。",
  },
};
export default codeErrorMessage;

urlsWithoutToken.js

// 不需要携带token的url数组
const urlsWithoutToken = [];

export default urlsWithoutToken;

简单使用方式(配合 dva 使用)

// 导入依赖
import { request } from "umi";

export function getApi(params) {
  return request("/xxx/xxx", {
    method: "GET",
    params,
  });
}
// dva中示例代码
yield call(getApi, { name: 'xxx' }),

更多资料


文章作者: Ming Hui
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ming Hui !
评论
  目录