Stories

Detail Return Return

axios多個baseURL封裝+vite跨域代理多個baseURL連接 - Stories Detail

公共封裝

import axios from 'axios';
import { MessagePlugin } from 'tdesign-vue-next';
import { getStorageToken } from '@/utils/index';

const api1 = axios.create({
  baseURL: '/api1'
});
const api2 = axios.create({
  baseURL: '/api2'
});
const api3 = axios.create({
  baseURL: '/api3'
});

// 定義一個函數來添加攔截器,避免代碼重複
const addInterceptors = (instance: any) => {
  // 請求攔截器
  instance.interceptors.request.use(
    function (config: any) {
      config.headers.Authorization = getStorageToken();
      return config;
    },
    function (error: any) {
      // 請求錯誤
      return Promise.reject(error);
    }
  );

  // 響應攔截器
  instance.interceptors.response.use(
    function (response: any) {
      let res = response.data;
      if (res.code == 201) {
        MessagePlugin.error(res.message);
        return Promise.reject(res);
      } else if (res.code == 400) {
        MessagePlugin.error(res.message);
        return Promise.reject(res);
      } else if (res.code == 500) {
        MessagePlugin.error(res.message);
        return Promise.reject(res);
      } else if (res.status) {
        if (res.status == 401) {
          console.log('token過期,請聯繫管理員');
      }
      return Promise.resolve(response.data);
    },
    function (error: any) {
      if (error?.response?.data?.status == 401) {
        console.log('響應錯誤,token過期', error);
        // 去登錄...
      } else {
        MessagePlugin.error('出錯啦,請聯繫管理員');
      }
      return Promise.reject(error);
    }
  );
};

addInterceptors(api1);
addInterceptors(api2);
addInterceptors(api3);

export { api1, api2, api3 };

使用
比如你要使用api1的接口,可以新建一個文件,引入api1

import { api1 } from '@/api/index';

// 這裏你也可以添加一個base,根據實際需求自定義
let base = '/api1';

export const getUserInfo = () => {
  return api1({
    url: base + '/getUserInfo',
    method: 'get'
  });
};

一般情況下還要配合vite.config的跨域代理使用,將跨域代理封裝成一個函數減少重複代碼

// 代理配置的函數
const generateProxyConfig = (env: any) => {
  const proxyMap = {
    '/api1': 'https://www.aaa.com',
    '/api2': 'https://www.bbb.com',
    '/api3': 'https://www.ccc.com',
  };

  const proxyConfig: Record<string, any> = {};
  for (const [prefix, target] of Object.entries(proxyMap)) {
    proxyConfig[prefix] = {
      target,
      changeOrigin: true,
      rewrite: (path: string) => path.replace(new RegExp(`^${prefix}`), '')
    };
  }
  return proxyConfig;
};

export default defineConfig(({ mode }) => {
  const root = process.cwd();
  const env: any = loadEnv(mode, root);
  return {
    base: env.VITE_PUBLIC_PATH,
    server: {
      host: '0.0.0.0',
      open: false,
      // 為開發服務器配置自定義代理規則-用於開發時的代理
      proxy: generateProxyConfig(env)
    },
  };
});

最後請求的接口經過代理會變成如下內容

'/api1/api1/getUserInfo' -> 'https://www.aaa.com/api1/getUserInfo'

如果生產環境後端沒有配置nginx代理,那麼前端在發佈生產時,vite.config.ts文件內的跨域代理配置要註釋掉,而且axios的baseURL需要替換為真實的https連接,如下:

// axios內的修改

const api1 = axios.create({
  baseURL: 'https://www.aaa.com'
});
const api2 = axios.create({
  baseURL: 'https://www.bbb.com'
});
const api3 = axios.create({
  baseURL: 'https://www.ccc.com'
});
// vite.config.ts的修改

export default defineConfig(({ mode }) => {
  const root = process.cwd();
  const env: any = loadEnv(mode, root);
  return {
    base: env.VITE_PUBLIC_PATH,
    server: {
      host: '0.0.0.0',
      open: false,
      // 為開發服務器配置自定義代理規則-用於開發時的代理
      // proxy: generateProxyConfig(env) // 新增
    },
  };
});
user avatar xiaoxxuejishu Avatar humi Avatar
Favorites 2 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.