欢迎光临
我们一直在努力

芋道项目部署时,前端和门户网站如何通过 Nginx 转发后台接口,而不直接暴露后端地址

在部署芋道项目时,很多人一开始都会直接让前端去请求后端地址,比如:

http://后端域名/admin-api

或者打包后前端里还残留着:

http://localhost:48082

这样会带来几个常见问题:

  • 后端地址直接暴露给用户
  • 容易出现跨域问题
  • 前端打包后接口还是请求 localhost
  • 页面刷新后 404
  • 更换后端地址时,还要重新改前端代码

更推荐的做法是:

  • 前端页面访问自己的域名
  • 前端请求接口时,也走自己的域名
  • 由 Nginx 再把接口请求转发到真正的后端服务

这篇文章把这个问题完整讲清楚,包括:

  • 为什么不能直接写 localhost
  • 为什么推荐前端走同域名请求
  • 芋道管理后台前端配置怎么写
  • 门户网站前端配置怎么写
  • Nginx 怎么转发
  • 页面刷新 404 怎么解决
  • 常见报错怎么排查

  • 一、问题现象

    很多人部署完前端后,打开页面会发现:

    • 登录验证码请求失败
    • 接口请求地址还是 localhost
    • 浏览器控制台报错
    • 页面一刷新就 404
    • 明明后端在服务器上运行,前端却请求不到

    例如浏览器里出现这样的请求地址:

    http://localhost:48082/admin-api/system/captcha/get

    这就是典型问题。

    这里一定要明白:

    前端页面是在用户浏览器里运行的。

    当前端去请求 localhost:48082 时,请求的不是你的服务器,而是用户自己电脑的 localhost。

    所以用户当然访问不到你服务器上的后端。


    二、正确思路:前端请求自己的域名,Nginx 再转发到后端

    正确做法不是让前端直接写后端地址,而是这样:

    假设:

    • 管理后台前端域名:admin.example.com
    • 门户网站前端域名:www.example.com
    • 后端服务运行在服务器本机:127.0.0.1:48082

    那么前端应该这样请求:

    管理后台

    前端请求:

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

    Nginx 转发到:

    http://127.0.0.1:48082/admin-api/…

    门户网站

    前端请求:

    https://www.example.com/api/…

    或者有些项目会写成:

    https://www.example.com/app-api/…

    Nginx 转发到:

    http://127.0.0.1:48082/api/…

    或者:

    http://127.0.0.1:48082/app-api/…


    三、为什么这样做更好

    1. 后端地址不用暴露

    用户只看到前端自己的域名,看不到真实后端地址和端口。

    2. 避免跨域

    因为前端和接口都走同一个域名或同源路径,浏览器不会拦截。

    3. 更方便管理

    以后后端换端口、换机器、换部署方式,只需要改 Nginx,不需要重新改前端代码。

    4. 更安全

    后端服务甚至可以只监听 127.0.0.1,完全不对公网开放。


    四、前端配置文件怎么写

    这一部分是很多新手最容易迷糊的地方。

    你要记住一个核心原则:

    前端不要直接写真实后端地址,而是写接口前缀。

    也就是不要写:

    baseURL: 'http://127.0.0.1:48082'

    或者:

    baseURL: 'http://后端域名'

    而应该写成:

    baseURL: '/admin-api'

    或者:

    baseURL: '/api'

    这样前端发请求时,请的就是当前站点自己的域名,再由 Nginx 去转发。


    五、门户网站前端配置文件示例

    你给出的门户配置文件是这样的:

    // 配置文件
    export const config = {
    // 开发环境用完整地址,生产环境通过 nginx 转发
    baseURL: '/api',
    default_headers: 'application/json'
    };

    这个写法其实就是比较标准的生产环境写法。

    它的意思是:

    • 前端代码里请求接口时,统一走 /api
    • 浏览器实际访问时,会自动拼成当前域名下的 /api
    • Nginx 再把 /api 转发到真正的后端服务

    例如:

    前端代码里请求:

    config.baseURL + '/user/info'

    最终就是:

    /api/user/info

    浏览器实际发出的请求是:

    https://www.example.com/api/user/info

    然后 Nginx 转发到:

    http://127.0.0.1:48082/api/user/info


    门户网站推荐写法

    // 配置文件
    export const config = {
    // 生产环境通过 nginx 转发到后端
    baseURL: '/api',
    default_headers: 'application/json'
    };


    如果你的门户项目开发环境和生产环境要区分

    也可以写成这种方式,更容易理解:

    const isDev = process.env.NODE_ENV === 'development';

    export const config = {
    baseURL: isDev ? 'http://127.0.0.1:48082/api' : '/api',
    default_headers: 'application/json'
    };

    这样含义就很清楚:

    • 本地开发时,前端直接请求本地后端
    • 生产环境部署后,前端只请求 /api
    • 由 Nginx 去转发

    六、芋道管理后台前端配置文件示例

    芋道管理后台通常是 Vite 项目,很多时候会在 .env 文件里配接口地址。

    比如原来有人会写成:

    VITE_BASE_URL='http://localhost:48082'
    VITE_API_URL=/admin-api

    这个就有问题。

    因为它会导致前端最终请求:

    http://localhost:48082/admin-api/…

    浏览器里这个 localhost 指向的是用户自己电脑,不是服务器。


    芋道管理后台推荐写法

    VITE_BASE_URL=''
    VITE_API_URL=/admin-api

    这样最终拼接出来的地址就是:

    /admin-api/…

    浏览器实际访问时会变成:

    https://admin.example.com/admin-api/system/captcha/get

    然后由 Nginx 转发到:

    http://127.0.0.1:48082/admin-api/system/captcha/get


    芋道后台前端配置的理解方式

    如果你的请求封装代码里是这样拼接的:

    baseURL = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL

    那么:

    VITE_BASE_URL=''
    VITE_API_URL=/admin-api

    最终结果就是:

    '' + '/admin-api' = '/admin-api'

    这正是我们想要的效果。


    芋道后台环境变量完整示例

    # 开发环境:本地只启动前端项目,依赖开发环境(后端、APP)
    NODE_ENV=production

    VITE_DEV=true

    # 请求路径
    VITE_BASE_URL=''

    # 文件上传类型:server – 后端上传,client – 前端直连上传,仅支持S3服务
    VITE_UPLOAD_TYPE=server

    # 接口地址
    VITE_API_URL=/admin-api

    # 是否删除debugger
    VITE_DROP_DEBUGGER=false

    # 是否删除console.log
    VITE_DROP_CONSOLE=false

    # 是否sourcemap
    VITE_SOURCEMAP=true

    # 打包路径
    VITE_BASE_PATH=/

    # 输出路径
    VITE_OUT_DIR=dist

    # 商城H5会员端域名
    VITE_MALL_H5_DOMAIN=''

    # 验证码的开关
    VITE_APP_CAPTCHA_ENABLE=true

    # GoView域名
    VITE_GOVIEW_URL=''

    这里最关键的只有两个:

    VITE_BASE_URL=''
    VITE_API_URL=/admin-api


    七、管理后台 Nginx 配置示例

    假设:

    • 管理后台域名:admin.example.com
    • 前端静态文件目录:/www/wwwroot/admin-web/dist
    • 后端服务:127.0.0.1:48082

    server {
    listen 80;
    server_name admin.example.com;

    root /www/wwwroot/admin-web/dist;
    index index.html index.htm;

    # 管理后台接口转发
    location /admin-api/ {
    proxy_pass http://127.0.0.1:48082/admin-api/;
    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;
    }

    # 如果项目有 websocket,可加这个
    location /infra/ws/ {
    proxy_pass http://127.0.0.1:48082/infra/ws/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    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;
    }

    # 前端单页应用刷新防 404
    location / {
    try_files $uri $uri/ /index.html;
    }
    }


    八、门户网站 Nginx 配置示例

    如果你的门户配置文件里写的是:

    baseURL: '/api'

    那 Nginx 就应该把 /api 转发到后端。

    假设:

    • 门户网站域名:www.example.com
    • 前端静态文件目录:/www/wwwroot/portal-web/dist
    • 后端服务:127.0.0.1:48082

    server {
    listen 80;
    server_name www.example.com;

    root /www/wwwroot/portal-web/dist;
    index index.html index.htm;

    # 门户接口转发
    location /api/ {
    proxy_pass http://127.0.0.1:48082/api/;
    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;
    }

    # 前端单页应用刷新防 404
    location / {
    try_files $uri $uri/ /index.html;
    }
    }


    九、前端配置和 Nginx 配置要一一对应

    这是最重要的一点之一。

    管理后台

    如果前端写的是:

    VITE_API_URL=/admin-api

    那么 Nginx 就必须写:

    location /admin-api/ {
    proxy_pass http://127.0.0.1:48082/admin-api/;
    }


    门户网站

    如果前端写的是:

    baseURL: '/api'

    那么 Nginx 就必须写:

    location /api/ {
    proxy_pass http://127.0.0.1:48082/api/;
    }


    不能乱配

    比如前端写的是:

    baseURL: '/api'

    但 Nginx 却只配了:

    location /admin-api/

    那前端请求 /api/… 时,Nginx 根本接不住,请求自然就失败了。

    所以一定要记住一句话:

    前端 baseURL 写什么,Nginx 就要代理什么。


    十、后端最好只监听本机

    既然前端已经通过 Nginx 转发到后端,那么后端就没必要再对公网暴露。

    例如 Spring Boot 可以这样配置:

    server:
    port: 48082
    address: 127.0.0.1

    这样意味着:

    • 外部用户无法直接访问 48082
    • 只能通过 Nginx 代理访问
    • 更安全,也更规范

    十一、为什么页面刷新会 404

    很多 Vue 项目部署后,进入某个页面没事,但一刷新就 404。

    例如访问:

    https://admin.example.com/system/user

    前端路由能正常展示。
    但刷新时,浏览器会直接请求服务器上的 /system/user 文件。

    服务器发现没有这个真实文件,就返回 404。

    解决办法就是:

    location / {
    try_files $uri $uri/ /index.html;
    }

    这句的意思是:

    • 先找真实文件
    • 再找真实目录
    • 都没有就返回 index.html

    然后再由 Vue Router 接管页面路由。


    十二、常见错误排查

    1. 前端还在请求 localhost

    说明前端配置没有改对,或者改完后没有重新打包。

    重点检查:

    芋道后台

    VITE_BASE_URL=''
    VITE_API_URL=/admin-api

    门户网站

    baseURL: '/api'


    2. 页面正常,接口 404

    说明 Nginx 没有正确代理接口路径。

    检查:

    • 前端写的是 /admin-api 还是 /api
    • Nginx 有没有对应的 location
    • proxy_pass 路径是否一致
    • 后端服务是否真的运行在 127.0.0.1:48082

    3. 刷新页面 404

    说明没有写:

    try_files $uri $uri/ /index.html;


    4. 接口返回的是 HTML 页面

    这通常说明接口请求没有匹配到代理规则,而是被:

    location / {
    try_files $uri $uri/ /index.html;
    }

    接住了。

    本质上就是接口代理规则写错了,或者顺序有问题。


    5. 改了 Nginx 配置但没有生效

    每次改完配置后,都要执行:

    nginx -t

    检查配置语法。

    没问题后再执行:

    nginx -s reload

    重新加载配置。


    十三、最容易理解的一套最终方案

    管理后台前端配置

    VITE_BASE_URL=''
    VITE_API_URL=/admin-api

    管理后台 Nginx

    location /admin-api/ {
    proxy_pass http://127.0.0.1:48082/admin-api/;
    }


    门户网站前端配置

    export const config = {
    baseURL: '/api',
    default_headers: 'application/json'
    };

    门户网站 Nginx

    location /api/ {
    proxy_pass http://127.0.0.1:48082/api/;
    }


    最终效果

    管理后台

    浏览器请求:

    https://admin.example.com/admin-api/system/captcha/get

    Nginx 转发到:

    http://127.0.0.1:48082/admin-api/system/captcha/get

    门户网站

    浏览器请求:

    https://www.example.com/api/user/info

    Nginx 转发到:

    http://127.0.0.1:48082/api/user/info


    十四、总结

    芋道项目和门户网站在部署时,不要让前端直接写真实后端地址,更不要写 localhost。

    正确方式是:

    • 前端请求自己的域名
    • 接口使用相对路径,例如 /admin-api、/api
    • Nginx 负责把请求转发到真正的后端服务
    • 前端路由通过 try_files 解决刷新 404
    • 后端只监听 127.0.0.1,不直接暴露公网

    一句话总结:

    前端只认自己的域名,后端由 Nginx 在服务器内部转发。


    十五、可直接复制的最简模板

    管理后台前端配置

    VITE_BASE_URL=''
    VITE_API_URL=/admin-api

    管理后台 Nginx

    server {
    listen 80;
    server_name admin.example.com;
    root /www/wwwroot/admin-web/dist;
    index index.html;

    location /admin-api/ {
    proxy_pass http://127.0.0.1:48082/admin-api/;
    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 / {
    try_files $uri $uri/ /index.html;
    }
    }

    门户网站前端配置

    export const config = {
    baseURL: '/api',
    default_headers: 'application/json'
    };

    门户网站 Nginx

    server {
    listen 80;
    server_name www.example.com;
    root /www/wwwroot/portal-web/dist;
    index index.html;

    location /api/ {
    proxy_pass http://127.0.0.1:48082/api/;
    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 / {
    try_files $uri $uri/ /index.html;
    }
    }


    赞(0)
    未经允许不得转载:171主机测评 » 芋道项目部署时,前端和门户网站如何通过 Nginx 转发后台接口,而不直接暴露后端地址
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址