当前位置: 首页 > article >正文

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

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

前言

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

问题描述

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

我们的代理配置如下:

// 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 调用代码:

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),请求可能被错误的规则处理

解决方案

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

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

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

1. Axios baseURL 与相对路径混淆

// 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 的影响

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

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

3. 路径重写错误

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

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

4. 代理规则顺序问题

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

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

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

// 配置文件
[`${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 请求取消与代理的交互

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

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

调试代理问题的技巧

  1. 添加详细日志

    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 配置

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

结论

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

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

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


http://www.kler.cn/a/590903.html

相关文章:

  • 从信息熵上看图像
  • Linux 网络基础设置
  • 利用Python爬虫获取Shopee(虾皮)商品详情:实战指南
  • 导出的使用
  • zabbix统计闲置资产
  • centos6.10 编译gcc11.5.0 支持mutilib(32bit,64bit)glibc2.11.3
  • 蓝桥杯备考:特殊01背包问题——》集合subset
  • c++图论(二)之图的存储图解
  • wx142基于django+vue+uniapp的摄影竞赛小程序
  • leetcode-47.全排列II
  • 迷你主机与普通台式电脑区别
  • 【conda activate无效】 conda: error: argument COMMAND: invalid choice: ‘activate‘
  • H-ZERO自定义全局字体 支持项目个性化字体需求
  • 【蓝桥杯速成】| 6.背包问题(01版)
  • C++11 详解版本1.0
  • Python 生成数据(绘制简单的折线图)
  • Redis和MongoDB的区别
  • POJ2301——Beat the Spread!、POJ3624——Charm Bracelet(0-1背包)、POJ2479——Maximum sum
  • 青少年编程与数学 02-011 MySQL数据库应用 04课题、数据库对象
  • 人工智能领域大模型、大模型使用、AI工作流 学习路径