在项目中,为了方便使用,对axios进行了二次封装,原因如下:

  1. 由于内网服务器的安全策略,put、delete 等方法的请求无法发送到后台
  2. 为了方便快速对接后端服务器,api 接口的前缀、安全策略过期时间等通用配置应该抽离

公共配置抽离

假设后端 api 的前缀地址是://1.1.1.1/api/,安全过期时间是 5000ms.

那么通用配置信息如下:

const CONFIG = {
  baseURL: "//1.1.1.1/api/",
  timeout: 5000
};

// ...

const instance = axios.create({ CONFIG });

// ...

export default instance;
1
2
3
4
5
6
7
8
9
10
11
12

编写拦截器

“拦截器”的做法来源于设计模式中的“装饰器模式”,它能在不改变原有函数逻辑的情况下,添加其他业务逻辑。

低耦合的设计非常适用于参数过滤、中间层拦截等场景。

请求拦截器

考虑到业务场景,请求到后端的数据需要在 Headers 中带有认证数据。

同时,由于不支持 put、patch、delete 方法,只能在 headers 中通过添加字段来标识。

const handleRequest = config => {
  config.headers.common["Authorization"] = token.get() || "";

  const method = config.method.toUpperCase();
  switch (method) {
    case "PUT":
    case "PATCH":
    case "DELETE":
      //方法转换
      config.headers.common["X-Http-Method-Override"] = method;
      config.method = "POST";
      break;
    default:
      break;
  }

  return config;
};

instance.interceptors.request.use(handleRequest, error =>
  Promise.reject(error)
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

返回拦截器

当数据从后端返回,出现错误的时候,也做一层数据过滤拦截。

const hanldeResponseError = error => {
  const { response = {} } = error;
  switch (response.status) {
    case 401: // 401:用户未登录需要先登录
      console.log("Unauthorized");
      break;
    case 403:
      console.log("Forbidden");
      break;
    case 400: //操作失败
    case 422: //表单验证失败
      console.log(`Error: ${response.data.message}`);
      break;
    case 404:
    default:
      break;
  }
  return Promise.reject(error);
};

instance.interceptors.response.use(response => response, hanldeResponseError);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21