【Axios 开发中的代理配置陷阱与解决方案】

Axios 开发中的代理配置陷阱与解决方案

前言

在前端开发过程中,我们经常需要配置代理来解决跨域问题或连接后端服务。最近在一个项目中,我遇到了一个典型的代理配置问题,这个问题看似简单,但却容易被忽视。本文将分享这个经历,并总结一些在使用 Axios 和 Vite 进行开发时常见的代理配置陷阱。

问题描述

在一个使用 Vite 构建的 Vue 项目中,我们使用了公司内部二次封装的 Axios 组件库来请求后端 API。Axios 配置了 baseURL/web,API 请求路径前缀为 /bizapp/api

我们的代理配置如下:

javascript 复制代码
// vite.config.ts
server: {
  proxy: {
    [`/web/bizapp/api`]: {
      target: env.VITE_BASE_URL,
      changeOrigin: true,
      rewrite: (path) => path.replace(new RegExp(`^/bizapp/api`), ''),
      // ...
    },
    '/web': {
      target: env.VITE_PROXY,
      changeOrigin: true,
      rewrite: (path: string) => path.replace(/^\/web/, '')
    },
    // ...
  }
}

API 调用代码:

typescript 复制代码
const MODULE_PATH = `${`/bizapp/api`}/alarmInfo/`;

export function getAlarmInfo(): Promise<GetAlarmInfoVO[]> {
  return request.get({
    url: `${MODULE_PATH}findAlarmForDay`
  });
}

然而,当我们发起请求时,收到了 500 错误:

复制代码
responseURL: "http://10.192.41.94:5173/web/bizapp/api/alarmInfo/findAlarmForDay"
status: 500
statusText: "Internal Server Error"
responseText: "{\"resultCode\":\"TCM-999\",\"resultMsg\":\"{\\\"exceptionMessage\\\":\\\"No static resource bizapp/api/alarmInfo/findAlarmForDay.\\\",\\\"data\\\":null}\",\"data\":null}"

问题分析

通过分析错误信息和配置,我们发现了几个关键问题:

  1. Axios baseURL 的影响 :Axios 的 baseURL 配置会自动给所有请求添加前缀。我们在代码中请求 /bizapp/api/...,但由于 Axios 配置了 baseURL: '/web',实际发出的请求变成了 /web/bizapp/api/...

  2. 代理规则不匹配 :我们的代理规则 /web/bizapp/api 的 rewrite 函数只替换了 /bizapp/api 部分,没有考虑 /web 前缀

  3. 代理规则优先级 :由于有两个可能匹配的规则(/web/bizapp/api/web),请求可能被错误的规则处理

解决方案

修改代理配置,正确处理完整的路径前缀:

javascript 复制代码
[`/web/bizapp/api`]: {
  target: env.VITE_BASE_URL,
  changeOrigin: true,
  rewrite: (path) => path.replace(new RegExp(`^/web/bizapp/api`), ''), // 修改这里,完整替换前缀
  // ...
}

其他常见的 Axios 与代理配置陷阱

1. Axios baseURL 与相对路径混淆

javascript 复制代码
// Axios 配置
axios.defaults.baseURL = '/api';

// 错误用法
axios.get('users'); // 正确,会请求 /api/users
axios.get('/users'); // 注意:这会请求 /api/users,而不是 /users
axios.get('https://example.com/data'); // 正确,完整 URL 会忽略 baseURL

2. 忽略了 Axios 拦截器对 URL 的影响

javascript 复制代码
// 拦截器可能修改 URL
axios.interceptors.request.use(config => {
  // 这里的修改会影响最终请求的 URL
  config.url = `/v2${config.url}`;
  return config;
});

// 代理配置需要考虑拦截器的影响
'/api/v2': {
  target: 'http://backend-server.com',
  // ...
}

3. 路径重写错误

javascript 复制代码
// 错误示例
'/api': {
  target: 'http://backend-server.com',
  rewrite: (path) => path.replace('/api', '') // 错误:没有使用 ^ 匹配开头
}

// 正确示例
'/api': {
  target: 'http://backend-server.com',
  rewrite: (path) => path.replace(/^\/api/, '') // 正确:使用 ^ 确保只替换路径开头
}

4. 代理规则顺序问题

javascript 复制代码
// 错误顺序
'/api': { /* ... */ },
'/api/special': { /* ... */ } // 永远不会匹配到,因为 '/api' 已经匹配了所有以 '/api' 开头的请求

// 正确顺序
'/api/special': { /* ... */ }, // 先定义更具体的规则
'/api': { /* ... */ }

5. 忽略了环境变量中的斜杠

javascript 复制代码
// 配置文件
[`${env.API_PREFIX}`]: { // 如果 API_PREFIX 在环境变量中已包含斜杠,可能导致问题
  target: env.API_TARGET,
  // ...
}

// 更安全的写法
[env.API_PREFIX.startsWith('/') ? env.API_PREFIX : `/${env.API_PREFIX}`]: {
  target: env.API_TARGET,
  // ...
}

6. Axios 请求取消与代理的交互

javascript 复制代码
// 使用取消令牌
const source = axios.CancelToken.source();
axios.get('/api/data', {
  cancelToken: source.token
});

// 如果在请求完成前取消,代理可能仍会处理请求,但客户端不会接收响应
source.cancel('Operation canceled.');

调试代理问题的技巧

  1. 添加详细日志

    javascript 复制代码
    configure: (proxy, options) => {
      proxy.on('error', (err, req, res) => {
        console.log('代理错误:', err, '请求路径:', req.url);
      });
      proxy.on('proxyReq', (proxyReq, req, res) => {
        console.log('代理请求:', req.method, req.url);
        console.log('代理目标:', target + req.url.replace(/* 重写规则 */));
      });
      proxy.on('proxyRes', (proxyRes, req, res) => {
        console.log('代理响应:', proxyRes.statusCode, '请求路径:', req.url);
      });
    }
  2. 使用浏览器开发工具:检查网络请求的详细信息,包括请求 URL、响应状态和响应内容

  3. 直接测试后端 API:使用 Postman 或类似工具直接请求后端 API,确认 API 本身是否正常工作

  4. 检查 Axios 配置

    javascript 复制代码
    axios.interceptors.request.use(config => {
      console.log('完整请求配置:', config);
      console.log('最终请求 URL:', config.baseURL + config.url);
      return config;
    });

结论

在前端开发中,Axios 的 baseURL 配置与代理设置的交互是一个容易被忽视的问题点。特别需要注意 baseURL 对请求路径的影响,以及代理规则的匹配顺序和路径重写逻辑。

通过正确理解这些机制,并采用合适的调试技巧,我们可以更高效地解决代理配置问题,提升开发效率。

希望这篇文章能帮助你避免类似的陷阱,让前端开发过程更加顺畅!

相关推荐
做测试的小薄15 分钟前
当 Selenium 的 click() /send_keys()等方法失效时:JavaScript 在 UI 自动化测试中的神奇用法
javascript·自动化测试·selenium·ui
MyhEhud17 分钟前
Kotlin 中 also 方法的用法和使用场景
前端·kotlin
小莫爱编程30 分钟前
HTML,CSS,JavaScript
前端·css·html
陈大鱼头1 小时前
AI驱动的前端革命:10项颠覆性技术如何在LibreChat中融为一体
前端·ai 编程
Gazer_S2 小时前
【解析 ECharts 图表样式继承与自定义】
前端·信息可视化·echarts
剪刀石头布啊2 小时前
视觉格式化模型
前端·css
一 乐2 小时前
招聘信息|基于SprinBoot+vue的招聘信息管理系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·招聘系统
念九_ysl2 小时前
Vue3 + ECharts 数据可视化实战指南
前端·信息可视化·echarts
Gazer_S2 小时前
【Auto-Scroll-List 组件设计与实现分析】
前端·javascript·数据结构·vue.js
前端加油站2 小时前
前端开发人员必备的Mac应用
前端