axios有多个baseURL怎么处理?

假如一个项目中有多个类型接口,他们的baseurl是不一致的,怎么统一封装呢?

import axios from 'axios';

// 创建axios实例
const service = axios.create({
  baseURL: '/api'
});

// 请求拦截器;
service.interceptors.request.use(
  function (config: any) {},
  function (error: any) {}
);

// 响应拦截器;
service.interceptors.response.use(
  function (response: any) {},
  function (error: any) {}
);

export default service;

假如现在有两个接口,baseURL如下
1、'/server'
2、'/question'
怎么封装更好呢,单独创建一个新的文件根据不同baseURL封装还是同一个文件创建不同axios实例?下面的方式可行吗?

const service = axios.create({
  baseURL: '/api'
});

// 创建不同 baseURL 的 axios 实例
const service1 = axios.create({
  baseURL: '/server'
});

const service2 = axios.create({
  baseURL: '/question'
});

// 定义一个函数来添加拦截器,避免代码重复
const addInterceptors = (instance: any) => {
  // 请求拦截器
  instance.interceptors.request.use(
    function (config: any) {},
    function (error: any) {}
  );

  // 响应拦截器
  instance.interceptors.response.use(
    function (response: any) {},
    function (error: any) {}
  );
};

// 为每个实例添加拦截器
addInterceptors(service);
addInterceptors(service1);
addInterceptors(service2);

// 导出所有实例
export { service, service1, service2 };
阅读 1.8k
3 个回答

方案结构

src/
├── api/
│ ├── request.ts // axios 工厂函数 + 拦截器封装
│ ├── server.ts // /server 接口封装
│ ├── question.ts // /question 接口封装

request.ts(axios 工厂函数)

import axios, { AxiosInstance } from 'axios';

// 创建 axios 实例的工厂函数
const createService = (baseURL: string): AxiosInstance => {
  const instance = axios.create({
    baseURL,
    timeout: 10000,
    headers: {
      'Content-Type': 'application/json'
    }
  });

  // 请求拦截器
  instance.interceptors.request.use(
    config => {
      // 可添加 token、日志等
      return config;
    },
    error => Promise.reject(error)
  );

  // 响应拦截器
  instance.interceptors.response.use(
    response => response.data,
    error => {
      // 可统一处理错误提示
      return Promise.reject(error);
    }
  );

  return instance;
};

export default createService;

server.ts(封装 /server 接口)

import createService from './request';

const serverService = createService('/server');

export const getServerStatus = () => serverService.get('/status');
export const postServerData = (data: any) => serverService.post('/data', data);

question.ts(封装 /question 接口)

import createService from './request';

const questionService = createService('/question');

export const getQuestionList = () => questionService.get('/list');
export const submitAnswer = (payload: any) => questionService.post('/submit', payload);

使用方式(例如在 React 中)

import { getServerStatus } from '@/api/server';
import { getQuestionList } from '@/api/question';

useEffect(() => {
  getServerStatus().then(res => console.log('Server:', res));
  getQuestionList().then(res => console.log('Questions:', res));
}, []);

加一个统一前缀啊,例如:/api
接口就变成:
/api/server
/api/question

前端配置 proxy 代理的时候 重写 path 去掉 api 就行
实际部署的时候,nginx 类似配置一下

只要一个service实例,线上环境根据路由前缀使用nginx反向代理就行

location /server {
    proxy_pass http://xx1;
    # ....
}
location /question {
    proxy_pass http://xx2;
   # ....
}
推荐问题