摘要:在前后端分离、Nginx 网关和内网转发越来越常见的今天,“前端到底该写什么地址”已经变成一个长期高频问题。表面上看,只是一个字符串 /loginhttp://192.168.xx.xx:8080/xxx/login 的区别,背后牵涉浏览器、网关、内网 IP 和部署环境的整体协作方式。如果这一层没有想清楚,开发环境和生产环境的行为很容易割裂,排查问题时也会格外艰难。本文从前端代码的写法出发,系统梳理开发环境与生产环境的常见模式,解释 /prod-api 前缀的作用以及 Nginx 在其中承担的角色,并说明“对外地址”和“对内地址”的真实含义。


一、完整路径的两段:浏览器到网关、网关到后端

可以将一次接口调用拆成两段路径。

  1. 第一段是浏览器到 Nginx。浏览器只认识“域名 + 路径”,例如 https://example.com/prod-api/login。这个地址通过 DNS 解析到 Nginx 所在的公网 IP,路径 /prod-api/login 交给 Nginx 配置解析。
  2. 第二段是 Nginx 到后端。Nginx 根据 locationproxy_pass 规则,将请求转发到内网中的后端服务,例如 http://192.168.88.102:8080/zzyl-admin/login。这里的 192.168.88.102 是后端 ECS 节点在 VPC 内的私有地址,只在云内部可见。

从架构角度看,浏览器和前端代码只应关心第一段;第二段的目标地址和路径前缀属于网关与后端服务之间的内部约定。


二、开发环境中的常见写法:直连后端与 devServer 代理

在本地开发阶段,后端服务通常运行在可直接访问的地址上。例如后端起在 http://localhost:8080/zzyl-admin,或某台内网机器的地址 http://192.168.88.102:8080/zzyl-admin。此时前端请求的写法一般有两类。

一种是直接写完整地址,例如:

axios.get('http://192.168.88.102:8080/zzyl-admin/login')

这种方式看起来直观,浏览器发出的请求完全不经过 Nginx,直接访问后端。优点是配置简单,缺点是容易触发跨域问题,也不利于日后无缝切换到生产环境入口


另一种是利用前端开发服务器(如 Vue CLI、Vite 等)提供的代理功能。在本地起一个前端 devServer,将所有以 /api/prod-api 开头的请求代理到后端,例如在配置中写:

// 伪代码示意
devServer: {
  proxy: {
    '/prod-api': {
      target: 'http://192.168.88.102:8080/zzyl-admin',
      changeOrigin: true,
    }
  }
}

前端代码只写:

axios.get('/prod-api/login')

浏览器发的请求是 http://localhost:8080/prod-api/login(devServer 地址),再由 devServer 代理到后端服务。这样可以在开发阶段提前模拟“网关前缀”的使用方式,后续切到 Nginx 时更平滑。


三、生产环境的推荐方式:baseURL + 统一前缀

在生产环境中,前端代码应尽量避免直接写内网 IP 或具体端口,推荐使用“统一前缀 + 域名”的方式,让所有接口调用都通过网关节点。(部署上线前,要升级我们的前端请求方式)

常见实践是为 axios 或其他 HTTP 客户端设置一个 baseURL

// axios 实例
const request = axios.create({
  baseURL: '/prod-api',
  timeout: 5000,
})

// 业务代码中只写相对路径
request.post('/login', data)
request.get('/user/page', { params: { pageNum: 1 } })

在浏览器眼中,真正发出的 URL 形态是:

  • https://example.com/prod-api/login

  • https://example.com/prod-api/user/page

“example.com” 是 Nginx 所在节点对外暴露的域名,“/prod-api” 前缀用于标记接口调用。前端代码既不关心后端部署在哪台 ECS,也不关心后端的端口号与应用上下文路径,这些信息留给 Nginx 的 proxy_pass 配置处理。(部署上线前,前端需要考虑如何与Nginx更加适配,即开始利用Nignx里配置的/prod-api隐藏真实内网IP

这种写法有三个直接效果:(1)开发代码更简洁,业务逻辑只围绕相对路径展开;(2)切换环境时,只需调整 baseURL 或构建时的环境配置;(3)前端与后端解耦,内网拓扑和节点调整可以通过运维配置完成。


四、Nginx 中 /prod-api 对应的内网地址映射

在 Nginx 的配置中,/prod-api 前缀通常会对应一个 location 块,用于将请求转发到后端内网地址。例如:

location /prod-api/ {
    proxy_pass http://192.168.88.102:8080/zzyl-admin/;

    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
}

可以这样理解这一段配置。

第一,location /prod-api/ 匹配所有以 /prod-api/ 开头的请求路径。浏览器发出的 /prod-api/login/prod-api/user/page 都会进入这里处理。

第二,proxy_pass http://192.168.88.102:8080/zzyl-admin/; 定义了上游后端服务的目标地址。192.168.88.102 是后端节点的内网 IP,8080 为后端应用端口,/zzyl-admin/ 是后端应用上下文路径。Nginx 会将 /prod-api/login 转发为 http://192.168.88.102:8080/zzyl-admin/login

第三,浏览器只与域名 https://example.com 和路径 /prod-api/login 打交道;Nginx 与后端通过内网地址通信。所谓“对外前缀 /prod-api/”与“对内前缀 /zzyl-admin/”,指的是同一条业务请求在两段路径上的表现形态。


五、对外地址与对内地址:角色分工的概念化理解

“对外地址”可以理解为用户可见的访问入口,由域名和公开路径构成,例如 https://example.com/prod-api/login。这个地址需要稳定、清晰、方便浏览器使用,也需要在 HTTPS、安全组、WAF 等层面接受统一治理。

“对内地址”可以理解为服务之间调用时使用的内部目标地址,例如 http://192.168.88.102:8080/zzyl-admin/login。这一地址通常位于 VPC 内网中,仅供 Nginx、后端节点和其他内部服务使用。这样的划分有助于在不暴露内部拓扑细节的情况下,对外提供统一接口。

在实践中,前端代码只应操作“对外地址”的相对路径,例如 /prod-api/login 或通过 baseURL 拼接的 /login“对内地址”交给 Nginx 配置和后端服务注册机制管理开发阶段临时直接写内网 IP 可以作为过渡方案,但在生产环境中保持网关统一入口,更符合长期维护和安全管理的需要。


六、前端接口地址的几条落地原则

围绕“前端地址究竟该怎么写”这一问题,可以提炼出几条简洁的原则,用于指导日常开发与部署配置。

  1. 开发阶段可以使用完整内网地址直连后端,但更推荐通过 devServer 代理提前使用 /prod-api 这类前缀,为生产环境的网关模式做好准备。
  2. 生产环境中尽量使用 baseURL + 相对路径 的形式,让浏览器只面对统一域名和前缀,将具体内网 IP 与后端路径隐藏在 Nginx 配置之下。
  3. 在 Nginx 中通过 location /prod-api/proxy_pass http://内网IP:端口/应用前缀/ 建立外部路径与内部服务之间的映射,用配置来表达“对外”和“对内”的角色分工。

在这样的设计下,前端代码的接口地址既易于阅读,也便于随环境切换;后端部署和节点调整集中在运维层,通过修改 Nginx 与云网络配置即可完成。对于 AI 运维场景中持续演化的服务体系,这一结构可以在保证灵活性的同时维持访问入口的长期稳定。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐