Vite 开发环境前后端端口隔离:解决 index.html 冲突问题

Vite 开发环境前后端端口隔离:解决 index.html 冲突问题

问题背景

在 Vue Vben Admin 项目的开发环境中,前端和后端运行在不同端口:

服务 地址 说明
前端(Vite Dev Server) http://localhost:5666 Vben SPA 应用
后端(ASP.NET Core) http://localhost:9999 接口服务器,也有自己的 index.html

问题出在:后端 http://localhost:9999 本身也是一个完整的 Web 站点,拥有自己的 index.html 首页。当前端通过 Vite 代理访问后端接口时,浏览器的首页请求也被代理到了后端 ,导致 http://localhost:5666 显示的是后端的 index.html,而不是 Vben 的 SPA 页面。

根因分析

修改前的错误配置

.env.development

bash 复制代码
VITE_GLOB_API_URL=/

vite.config.ts

ts 复制代码
server: {
  proxy: {
    '/': {
      target: 'http://localhost:9999',
      changeOrigin: true,
      secure: false,
      bypass: (req, res, options) => {
        const url = req.url;
        // 排除前端静态资源和页面路由
        if (url.startsWith('/vue/') ||
            url.endsWith('.html') ||
            url.endsWith('.js') ||
            url.endsWith('.css') ||
            url.endsWith('.png') ||
            // ... 更多后缀 ...
            url.endsWith('.eot')) {
          return false; // 不代理,让 Vite 处理
        }
      },
    },
  },
}

问题所在

这种配置采用的是排除法------把所有请求都代理到后端,然后逐个排除前端资源。这有两个致命缺陷:

  1. 根路径 / 无法排除 :当浏览器访问 http://localhost:5666/ 时,请求 URL 是 /,不以 /vue/ 开头,也不以任何静态资源后缀结尾,所以不会被 bypass 拦截,直接代理到了后端,返回后端的 index.html

  2. SPA 路由无法穷举 :前端 SPA 的路由(如 /vue/dashboard/vue/user/list)可能返回 HTML,也可能需要代理,无法用简单的后缀匹配来区分。

  3. 维护困难:每新增一种资源类型就要加一条 bypass 规则,容易遗漏。

解决方案

改用白名单法------只代理明确属于 API 的请求,其余全部由 Vite 处理。

核心思路:在前端侧加一个 /api 虚拟前缀,用来标记"这是 API 请求",Vite 代理转发时再去掉这个前缀。

修改后的配置

.env.development

bash 复制代码
# 接口地址(开发环境通过 /api 前缀区分前端页面和后端接口)
VITE_GLOB_API_URL=/api

vite.config.ts

ts 复制代码
server: {
  proxy: {
    '/api': {
      target: 'http://localhost:9999',
      changeOrigin: true,
      secure: false,
      // 去掉 /api 前缀,后端接口没有 /api 前缀
      rewrite: (path) => path.replace(/^\/api/, ''),
    },
  },
}

请求流转示意

text 复制代码
浏览器请求                    Vite 代理处理               转发到后端
─────────────────────────────────────────────────────────────────────
http://localhost:5666/vue/  → Vite 直接处理           → 返回 Vben 的 index.html
http://localhost:5666/api/user  → 匹配 /api 规则     → http://localhost:9999/user
http://localhost:5666/api/login → 匹配 /api 规则     → http://localhost:9999/login
http://localhost:5666/vue/assets/xxx.js → Vite 直接处理 → 返回前端静态资源

关键点:后端没有 /api 路径

后端的接口路径没有 /api 前缀,比如接口是:

  • http://localhost:9999/user
  • http://localhost:9999/login

/api 只是前端和 Vite 之间的"暗号",rewrite 规则会在转发前把 /api 去掉:

text 复制代码
前端发出: /api/user
  ↓ rewrite 去掉 /api
后端收到: /user

后端收到的请求路径和之前完全一样,无需任何后端改动。

生产环境不受影响

生产环境配置(.env.production)保持不变:

bash 复制代码
VITE_GLOB_API_URL=/

因为生产环境前后端部署在同一域名下(由 nginx 统一代理),不存在端口冲突和 index.html 覆盖的问题。

总结对比

对比项 修改前(排除法) 修改后(白名单法)
代理匹配规则 '/'(全部代理) '/api'(只代理 API)
API 前缀 /api(转发前 rewrite 去掉)
bypass 逻辑 需要列举排除规则 不需要
根路径 / 被代理到后端,返回后端首页 Vite 自己处理,返回 Vben 页面
维护性 差,需持续补充 bypass 规则 好,只需维护 /api 前缀
后端改动
相关推荐
光影少年2 小时前
react16-react19类组件完整生命周期(挂载/更新/卸载)
前端·javascript·react.js
这个昵称也不能用吗?3 小时前
eas 热更新相关
前端
KaMeidebaby3 小时前
卡梅德生物技术快报|葫芦科植物遗传转化:Fast‑TrACC 工程化优化:葫芦科植物遗传转化效率提升与成本控制
前端·其他·百度·新浪微博
换日线°4 小时前
vue 加入购物车抛物线动画
前端·javascript·vue.js
切糕师学AI4 小时前
为什么你的 SPA 网址必须包含 `#`?—— 前端路由 Hash 模式深度解析
前端·spa 网址·hash路由
冴羽4 小时前
超越Vibe Coding —— AI 辅助编程进阶指南
前端·javascript·ai编程
MXN_小南学前端5 小时前
自制和整理常用前端 AI Skills分享,从需求到页面(附github地址)
前端·ai编程
yuki_uix5 小时前
双 RAF + MutationObserver:微前端跳转后的滚动复原完整方案
前端
暗不需求5 小时前
一文吃透 React Context:跨层级通信的利器
前端·javascript·react.js