从 Vite Proxy 到 Nginx 反向代理:打通前后端分离部署的“最后一公里” ✨

🚀 从 Vite Proxy 到 Nginx 反向代理:打通前后端分离部署的“最后一公里”

嘿,各位前端和全栈的伙伴们!👋

你是否也经历过这样的“午夜惊魂”:在本地开发环境 (npm run dev) 中,前端项目与后端 API (Application Programming Interface, 应用程序编程接口) 完美交互,一切顺风顺水。然而,当你兴高采烈地执行 npm run build,将打包好的静态文件部署到 Nginx 上时,却发现所有的 API 请求都失败了!😱

浏览器控制台里一片红,不是 404 (Not Found) 就是 CORS (Cross-Origin Resource Sharing, 跨源资源共享) 错误。别慌,这几乎是每个走前后端分离部署路线的开发者都会遇到的经典问题。

今天,我们就来复盘这个从“开发”到“生产”的转变过程,彻底搞懂为什么 vite.config.js 里的 proxy 会“失效”,以及如何让 Nginx 接过代理的“接力棒”!

🤔 问题浮现:为什么 proxy 突然不灵了?

在开发阶段,我们通常会在 vite.config.js (或 vue.config.js) 中配置一个 proxy 来解决跨域问题。就像这样:

// vite.config.js
export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://192.168.31.73:8000', // 后端 API 网关地址
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  },
})

这个配置非常方便,它让 Vite 的开发服务器扮演了一个“中间人”的角色:

  1. 前端代码发起一个相对路径的请求,比如 /api/auth/captcha
  2. Vite 开发服务器拦截这个请求。
  3. Vite 将请求转发给真正的后端地址 http://192.168.31.73:8000

这个过程对浏览器是透明的,浏览器始终认为它在和同源的 Vite 服务器(如 localhost:3000)通信,从而巧妙地绕过了跨域限制。

然而,这一切的美好,都在你按下 npm run build 的那一刻结束了!

build 命令会将你的前端应用打包成一堆纯静态的 HTML (HyperText Markup Language, 超文本标记语言), CSS (Cascading Style Sheets, 层叠样式表), 和 JS (JavaScript) 文件。此时,Vite 开发服务器已经退出了历史舞台。你部署到服务器上的,只是这些静态文件,它们本身不具备任何代理能力。

当浏览器加载了 Nginx 上的 index.html,然后根据你的 JS 代码发起 /api/auth/captcha 请求时,这个请求实际上是发往 http://your-domain.com/api/auth/captcha。Nginx 收到这个请求,默认会去自己的网站根目录下寻找一个名为 /api 的文件夹,结果自然是——404 Not Found

✨ 解决方案:Nginx 登场,接过反向代理的接力棒!

既然 Vite 开发服务器“下班了”,我们就需要一个新的“中间人”来完成 API 请求的转发。这个角色,非 Nginx 莫属!

我们需要修改 Nginx 的配置文件,让它实现和 Vite proxy 同样的功能。这个技术,就叫做反向代理 (Reverse Proxy)

1. 找到你的 Nginx 配置文件

首先,你需要找到托管你前端项目的 Nginx 配置文件。在 Ubuntu 上,它通常位于 /etc/nginx/conf.d/ 目录下,比如 my-app.conf

一个典型的前端静态托管配置可能长这样:

server {
    listen 80;
    server_name your-domain.com;

    root /var/www/my-vue-admin; # 你 build 后的 dist 目录
    index index.html;

    # 处理 Vue/React 的 History 路由模式
    location / {
        try_files $uri $uri/ /index.html;
    }
}
2. 添加反向代理规则

现在,我们需要在这个 server 块里,为 /api 路径添加一个专门的 location 规则。

server {
    listen 80;
    server_name your-domain.com;

    root /var/www/my-vue-admin;
    index index.html;

    # --- 重点来了!新增的反向代理配置 ---
    # 告诉 Nginx:所有以 /api/ 开头的请求,都交给我处理!
    location /api/ {
        # 转发的目标地址,也就是你的后端 API 网关
        # 127.0.0.1 指的是 Nginx 服务器本身
        proxy_pass http://127.0.0.1:8000/;

        # (推荐) 添加一些请求头,让后端能获取到真实的客户端信息
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 这个 location / 规则必须放在后面,用于处理前端路由和静态资源
    location / {
        try_files $uri $uri/ /index.html;
    }
}

配置解读 🧐:

  • location /api/ { ... }:定义了一个匹配规则。当 Nginx 收到一个 URL (Uniform Resource Locator, 统一资源定位符) 以 /api/ 开头的请求时,就会应用这个规则。
  • proxy_pass http://127.0.0.1:8000/;:这是反向代理的核心!
    • proxy_pass 指令告诉 Nginx:“把这个请求转发给 http://127.0.0.1:8000”。
    • 末尾的 / 至关重要! 它起到了路径重写 (rewrite) 的作用。Nginx 会将请求 URL 中匹配 location 的部分 (/api/) 去掉,然后将剩余部分拼接到 proxy_pass 的地址后面。
      • 浏览器请求: /api/auth/captcha
      • Nginx 转发: http://127.0.0.1:8000/auth/captcha
      • 完美!这正是我们想要的效果!
3. 检查并重载 Nginx

修改完配置后,记得检查语法并让它生效:

# 检查配置文件语法是否正确
sudo nginx -t

# 如果语法正确,平滑地重新加载 Nginx 服务
sudo systemctl reload nginx

现在,清空浏览器缓存,重新访问你的网站。你会发现,所有的 API 请求都奇迹般地成功了!🎉

结语

这次排错之旅告诉我们,自动化部署的道路上充满了细节。一个看似简单的 sudo 免密问题,背后可能隐藏着 TTY、SSH 会话类型、sudoers 加载顺序和配置覆盖等一系列知识点。

当你遇到顽固的问题时,不要怀疑自己,也不要怀疑工具,而要像侦探一样,根据日志提供的线索,一步步缩小范围,最终找到那个隐藏在角落里的“真凶”。而最佳实践,往往就是为这些“坑”量身定制的优雅解决方案。


附录:总结与图表

📊 开发环境 vs 生产环境代理方案总结
环境代理角色配置地点工作原理
开发环境 👨‍💻Vite 开发服务器vite.config.js内存中的 Node.js 服务器拦截并转发请求
生产环境 🚀Nginx/etc/nginx/conf.d/*.confNginx 作为 Web 服务器,根据 location 规则进行反向代理
🗺️ Mermaid 流程图:Nginx 请求处理流程
浏览器发起请求
URL 是否以 '/api/' 开头?
匹配 'location /api/' 规则
Nginx 反向代理至
http://127.0.0.1:8000
匹配 'location /' 规则
Nginx 在 '/var/www/...' 目录
查找静态文件 (HTML/JS/CSS)
如果找不到, 返回 index.html
🔄 Mermaid 时序图:生产环境前后端交互
浏览器NginxAPI 网关 (Docker)后端服务 (Docker)GET / (请求首页)返回 index.html, app.js 等静态资源用户点击登录按钮POST /api/auth/loginproxy_pass 转发请求POST /auth/login内部路由转发返回认证结果 (Token)返回认证结果返回 API 响应 (Token)浏览器NginxAPI 网关 (Docker)后端服务 (Docker)
🚦 Mermaid 状态图:请求的不同命运
URL 匹配 /api/
URL 不匹配 /api/
Nginx接收请求
API请求
静态资源请求
后端处理
前端渲染
🏛️ Mermaid 类图:部署架构中的组件
"发起 HTTP 请求"
"反向代理 API 请求"
"内部服务调用"
Browser
+sendRequest(url)
Nginx
+listenPort: 80
+serveStaticFiles()
+reverseProxy(request)
ApiGateway
+listenPort: 8000
+routeRequest(request)
BackendService
+processLogic()
🔗 Mermaid 实体关系图:配置与服务的关系
NGINX_SERVER_BLOCKintlisten_portPKstringserver_nameLOCATION_BLOCKstringpathPKstringtypeBACKEND_SERVICEstringnamePKintportSTATIC_FILESstringroot_pathPK包含代理到 (如果 type='proxy')服务 (如果 type='static')
🧠 Markdown 思维导图
  • Vite Proxy 与 Nginx 反向代理
    • 核心问题
      • 开发环境 (npm run dev) 一切正常
      • 生产环境 (npm run build + Nginx) API 请求失败 (404 或 CORS)
    • 原因分析
      • Vite Proxy 的作用域
        • 仅在开发环境生效
        • 是一个 Node.js 开发服务器提供的内存代理功能
      • 生产环境的变化
        • npm run build 后,Vite 退出,只剩下静态文件
        • Nginx 成为 Web 服务器,但默认不知道如何处理 /api 请求
    • 解决方案:Nginx 反向代理
      • 角色转换
        • 让 Nginx 接替 Vite 开发服务器,成为新的“中间人”
      • Nginx 配置
        • 1. 找到配置文件
          • 通常在 /etc/nginx/conf.d/
        • 2. 添加 location /api/
          • 匹配所有 API 请求
        • 3. 使用 proxy_pass 指令
          • proxy_pass http://127.0.0.1:8000/;
          • 关键点:末尾的 / 实现路径重写
        • 4. (推荐) 设置代理请求头
          • proxy_set_header Host $host;
          • proxy_set_header X-Real-IP $remote_addr;
      • 生效配置
        • 检查语法:sudo nginx -t
        • 重载服务:sudo systemctl reload nginx
    • 总结
      • 开发代理 != 生产代理
      • Vite Proxy 是开发便利工具
      • Nginx 反向代理是生产环境的标准解决方案
      • 理解请求在不同环境下的流转路径是关键 🔑

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值