芋道项目部署:前端写死后端地址 vs Nginx 反向代理

两种方式的区别、风险与完整配置(小白也能照做)

很多同学第一次部署芋道(Ruoyi-Vue-Pro / 芋道源码)这种前后端分离项目,常见两种访问方式:

  1. 前端直接请求后端域名 (把 API 地址写死成 https://api.xxx.com
  2. 前端只请求自身域名,Nginx 反向代理转发到后端 (前端写 /api,Nginx 转发到 127.0.0.1:48081

这两种都能跑起来,但生产环境推荐的做法 很明确:

Nginx 反向代理(同域转发)更稳、更安全、更省心

下面用 芋道项目为例,带你从 0 配置到可用,并解释常见坑(比如你遇到的:为什么页面里会看到 localhost)。


1. 两种方式是什么?(先把概念讲明白)

方式 A:前端写死后端域名(直连后端)

结构通常是:

  • 前端:https://www.example.com
  • 后端:https://api.example.com(或 http://IP:48081

前端代码里直接写死:

js 复制代码
axios.defaults.baseURL = "https://api.example.com"

优点:

  • ✅ 配置简单,改个地址就能跑
  • ✅ 前端、后端可以独立部署到不同机器

缺点(生产更明显):

  • ❌ 需要配置 CORS(跨域),容易误配
  • ❌ 后端域名暴露在公网,攻击/扫描成本低
  • ❌ 统一限流、防刷、黑名单、WAF 不好做
  • ❌ Cookie/会话类场景容易踩坑(跨域 Cookie、SameSite)

方式 B:Nginx 反向代理(同域转发)

结构通常是:

  • 对外只暴露一个域名:https://www.example.com
  • 前端请求:https://www.example.com/api/...
  • Nginx 转发到:http://127.0.0.1:48081/...

前端代码只写相对路径:

js 复制代码
axios.defaults.baseURL = "/api"

优点(生产推荐):

  • ✅ 前后端同域:不用 CORS,Cookie/登录态更稳
  • ✅ 后端真实地址不暴露(甚至可以只监听 127.0.0.1)
  • ✅ Nginx 层可以统一做限流、防刷、日志审计、黑名单
  • ✅ 更接近真实生产架构(尤其是 Java 项目)

缺点:

  • ❌ 初次配置比直连稍复杂(但一次配置长期收益)

2. 你问的关键点:为什么页面里会看到 localhost?

这是很多人第一次用 Nginx 转发时的误会:

Nginx 的 proxy_pass http://127.0.0.1:48081,浏览器是看不到的。

浏览器只会看到自己请求的域名,比如 https://www.example.com/api/...

那为什么你在 Network 或页面里看到 localhost

只有几种可能:

  1. 前端代码仍然写死了 http://localhost:48081(最常见)
  2. 后端返回的数据里包含了绝对 URL(例如文件下载、图片访问地址)
  3. 后端返回 302/重定向,Location Header 拼成了 localhost
  4. 你看到的是 开发环境(npm run dev)的代理配置(dev 下正常)

后面文章会专门讲如何修。


3. 方式 A:前端写死后端地址(直连后端)怎么配置?

3.1 后端(芋道)部署

后端通常是 Spring Boot Jar,监听一个端口,比如 48081:

yaml 复制代码
server:
  port: 48081

如果你要直连后端域名(例如 api.example.com),一般会:

  • 给后端配置一个域名和证书(HTTPS)
  • 或直接暴露 IP:48081(不推荐)

⚠️ 安全建议:如果要暴露后端到公网,至少要做到:

  • 配防火墙允许的 IP/网段(如只允许前端服务器访问)
  • 访问限流(Nginx/WAF/网关)
  • 严格鉴权、权限校验、日志审计

3.2 前端配置 baseURL(直连)

假设后端对外是:

  • https://api.example.com/admin-api

前端配置(以常见封装为例):

js 复制代码
// 生产环境
axios.defaults.baseURL = "https://api.example.com"

如果你的后端 API 前缀是 /admin-api,那通常前端请求会是:

  • https://api.example.com/admin-api/xxx

3.3 CORS 必须处理(直连方式的核心)

因为前端域名和后端域名不同(跨域),必须配置 CORS,否则浏览器直接拦。

典型错误 :为了省事把 allowedOrigins=* 全放开

这在生产很危险。

更合理的做法是:

只允许你的前端域名:

  • https://www.example.com

(具体芋道版本/模块 CORS 配置位置可能不同,但原则一致:*别写成 ,别乱放开


4. 方式 B:Nginx 反向代理(同域转发)怎么配置?

这才是本篇文章的重点:芋道生产推荐方案

4.1 后端只监听本机(强烈推荐)

让后端对外"不可见",只给 Nginx 转发即可:

yaml 复制代码
server:
  port: 48081
  address: 127.0.0.1   # ★关键:仅本机可访问

并且防火墙不要放行 48081。

这样做的效果是:

✅ 外面扫描不到你的 Java 端口

✅ 只有 Nginx(同机)能访问后端


4.2 前端配置(只用相对路径)

前端不要再写后端域名,改成:

js 复制代码
axios.defaults.baseURL = "/api"

重新打包:

bash 复制代码
npm run build

dist 放到你的站点目录,比如:

/www/wwwroot/yudao-front/dist


4.3 Nginx 站点配置(宝塔可直接粘贴)

宝塔里:网站 → 设置 → 配置文件

写成类似下面(按你的实际域名、目录改一下):

nginx 复制代码
server {
    listen 80;
    server_name www.example.com;

    # 前端静态资源
    location / {
        root /www/wwwroot/yudao-front/dist;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    # 后端接口代理:把 /api/ 转到本机的 48081
    location /api/ {
        proxy_pass http://127.0.0.1:48081/;

        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;
    }
}

你可以先不配 HTTPS,通了以后再在宝塔里一键申请证书,然后把 80 升级到 443。


4.4 路径对齐:芋道常见 API 前缀怎么处理?

芋道经常有:

  • /admin-api(管理端)
  • /app-api(APP)
  • /mp-api(公众号/小程序,视项目而定)

你有两种常见选择:

选择 1:前端走 /api,Nginx 直接转发到后端根路径(推荐)

前端请求 /api/admin-api/...

Nginx 转发到 http://127.0.0.1:48081/admin-api/...

对应 Nginx:

nginx 复制代码
location /api/ {
  proxy_pass http://127.0.0.1:48081/;
}

这样 /api/ 会被去掉一层前缀,路径自然对齐。

选择 2:Nginx 做更细的拆分(更清晰)

比如:

nginx 复制代码
location /admin-api/ {
  proxy_pass http://127.0.0.1:48081/admin-api/;
}

location /app-api/ {
  proxy_pass http://127.0.0.1:48081/app-api/;
}

前端就直接请求 /admin-api/app-api,不需要再包一层 /api

两种都可以,推荐第 1 种(前端统一 /api,更利于后续加网关/限流)。


5. 常见坑:为什么出现 "localhost"?

5.1 如果 Network 里 Request URL 显示 localhost

说明:前端 baseURL 还是 localhost

检查是否有环境变量配置,例如:

  • .env.production
  • config.js
  • request.js

确保生产环境只用:

js 复制代码
baseURL: "/api"

5.2 如果 Response Body 里出现 localhost

说明:后端返回了拼好的绝对地址,常见于:

  • 上传文件返回访问 URL
  • 导出下载地址
  • 回调地址

解决思路:

  • 后端不要硬编码 localhost
  • 用配置项注入"外部访问域名"
  • 或返回相对路径,由前端拼成当前域名

5.3 如果是 302/跳转 Location 里出现 localhost

一般是 反向代理 header 没带全 或 Spring 没识别 forward headers。

Nginx 必带:

nginx 复制代码
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Spring Boot 建议开启:

yaml 复制代码
server:
  forward-headers-strategy: native

6. 两种方式到底怎么选?(最终推荐)

✅ 如果你是 Java 开发、部署芋道项目(你这种情况)

并且你说:不部署 PHP,只部署 Java 服务

那我的最终推荐非常明确:

生产环境优先选择:Nginx 反向代理(同域转发)

理由:更安全、无跨域、登录态更稳、运维能力更强

什么时候可以用"直连后端"?

  • 内部系统 / 内网访问
  • 测试环境
  • 前后端分开部署,且你有网关/WAF/限流能力

否则生产不建议。


7. 一个可直接照抄的"芋道 + 宝塔"部署清单

✅ 后端

  • server.port=48081
  • server.address=127.0.0.1
  • 防火墙不开放 48081

✅ 前端

  • baseURL="/api"
  • npm run build
  • dist 上传到宝塔站点目录

✅ Nginx(宝塔站点配置)

  • / → 前端静态资源
  • /api/proxy_pass http://127.0.0.1:48081/
  • 加全 proxy headers

✅ 验证

  • 浏览器 Network:Request URL 只出现 www.example.com/api/...
  • 不出现 localhost
  • 直接访问 IP:48081(公网)访问不到

8. 结语

部署这一步,很多人追求"先能跑起来",然后在生产上留下隐患。

你现在主动从"直连后端"升级到"同域反向代理",其实就是在做正确的工程化

相关推荐
pas13616 小时前
30-mini-vue 更新 element 的 props
前端·javascript·vue.js
魁首16 小时前
OpenAI Codex 深入剖析:下一代 AI 编程助手的架构与原理
前端·openai·ai编程
火星数据-Tina16 小时前
如何构建一个支持多终端同步的体育比分网站?
大数据·前端·数据库·websocket
IT_陈寒16 小时前
React 19 实战:5个新特性让你的开发效率提升50%!
前端·人工智能·后端
GuMoYu16 小时前
el-date-picker限制选择范围
前端·javascript·vue.js
冴羽17 小时前
JavaScript Date 语法要过时了!以后用这个替代!
前端·javascript·node.js
加油乐17 小时前
react使用Ant Design
前端·react.js·ant design
OEC小胖胖17 小时前
05|从 `SuspenseException` 到 `retryTimedOutBoundary`:Suspense 的 Ping 与 Retry 机制
前端·前端框架·react·开源库