从前端部署到请求转发:一篇搞懂 Nginx 是怎么把页面和接口路由起来的

发布时间:2026/6/30 7:06:42

从前端部署到请求转发:一篇搞懂 Nginx 是怎么把页面和接口路由起来的 摘要最近在用 Jenkins 部署前后端服务时我把后端 jar 包部署这条链路先跑通了接着开始补前端部署这块。前端和后端最大的区别在于后端通常是java -jar直接起服务而前端大多数是打包成静态文件再交给 Nginx 去提供访问。同时Nginx 还常常承担接口转发、HTTPS、安全加固、资源压缩等职责。刚开始接触这些配置时我最困惑的就是location到底是什么alias、index、try_files、proxy_pass分别在干什么浏览器请求一个 Nginx 的 IP 地址后它到底会被路由到哪里这篇文章就把这些问题从实际部署的角度讲清楚。一、为什么前端部署通常离不开 Nginx如果是一个典型的前端项目比如VueReact普通静态站点打包之后产物通常是一堆静态文件例如index.htmlmain.jsapp.css图片、字体、SVG 等资源这些文件本身并不会“自己跑起来”它们需要一个 Web 服务器去提供访问。而 Nginx 正好就很适合做这件事。所以前端部署时最常见的模式就是Jenkins 或本地打包出dist或 zip 包把打包产物放到目标服务器由 Nginx 提供静态资源访问再由 Nginx 把接口请求转发到后端服务可以把它理解成前端页面、JS、CSS由 Nginx 直接返回后端接口由 Nginx 转发给 Java 服务二、一个最常见的实际场景假设现在有这样一台服务器192.168.251.6上面部署了前端项目名qding-scc-front部署目录/usr/share/nginx/html/qding-scc-front后端Java 服务监听端口8162我希望浏览器这样访问访问前端页面http://192.168.251.6/qding-scc-front/访问后端接口http://192.168.251.6/api/qding/user/list那这个时候Nginx 就要负责判断这个请求是要找静态文件还是要转给后端接口如果请求的是前端单页应用路由比如/qding-scc-front/user/list找不到真实文件时应该怎么办这就是 Nginx 配置真正解决的问题。三、Nginx 在这个场景里扮演什么角色可以先看一张时序图。Java后端服务静态文件目录Nginx浏览器Java后端服务静态文件目录Nginx浏览器请求 http://192.168.251.6/qding-scc-front/查找 /usr/share/nginx/html/qding-scc-front/index.html返回 index.html返回前端页面请求 http://192.168.251.6/api/qding/user/list转发到 http://127.0.0.1:8162/user/list返回JSON返回接口数据这张图可以帮助理解同一个 IP同一个 80 端口浏览器看起来都在访问一台服务器但 Nginx 会根据 URL 路径把请求分发到不同地方四、nginx.conf和conf.d到底该怎么分工这是我一开始很困惑的地方。很多机器上默认的主配置里会有类似这样的内容http { include /etc/nginx/conf.d/*.conf; server { listen 80; server_name _; root /usr/share/nginx/html; } }这说明 Nginx 的配置通常分成两层1.nginx.conf更适合放全局配置比如worker 数量日志格式gzipssl_protocolsinclude /etc/nginx/conf.d/*.conf代理公共请求头2./etc/nginx/conf.d/*.conf更适合放具体业务配置比如某个前端项目的路由某个后端接口的代理某个域名的 HTTPS 配置我的建议如果你一台服务器上以后要挂多个前端多个后端多套路径转发那就优先用conf.d拆配置文件不要所有东西都堆进nginx.conf。例如/etc/nginx/conf.d/qding-scc-front.conf /etc/nginx/conf.d/order-front.conf /etc/nginx/conf.d/user-front.conf这样更容易维护也更方便排查问题。五、location到底是什么可以先把它理解成一句话location就是在定义某一类 URL 请求应该怎么处理。比如location /qding-scc-front/ { ... }意思就是只要请求路径以/qding-scc-front/开头就按这里面的规则处理。再比如location /api/qding/ { ... }意思就是只要请求路径以/api/qding/开头就按这里面的规则处理。六、一个完整的前后端路由例子先看配置server { listen 80; server_name _; location /qding-scc-front/ { alias /usr/share/nginx/html/qding-scc-front/; index index.html; try_files $uri $uri/ /qding-scc-front/index.html; } location /api/qding/ { proxy_pass http://127.0.0.1:8162/; } }下面逐行解释。七、location /qding-scc-front/是什么意思这一段表示location /qding-scc-front/ { ... }所有以/qding-scc-front/开头的请求都会进入这里。例如/qding-scc-front//qding-scc-front/index.html/qding-scc-front/static/js/app.js/qding-scc-front/user/list八、alias是什么意思alias /usr/share/nginx/html/qding-scc-front/;alias可以理解成把 URL 路径映射到一个真实磁盘目录。也就是浏览器访问/qding-scc-front/...Nginx 去/usr/share/nginx/html/qding-scc-front/...找文件实际例子 1访问静态 JS 文件浏览器请求http://192.168.251.6/qding-scc-front/static/js/app.jsNginx 会去磁盘上找/usr/share/nginx/html/qding-scc-front/static/js/app.js如果存在就直接返回这个文件。九、index是什么意思index index.html;它表示如果访问的是一个目录就默认返回这个目录下的index.html。实际例子 2访问首页浏览器请求http://192.168.251.6/qding-scc-front/这不是一个具体文件而是一个目录。此时 Nginx 会默认找/usr/share/nginx/html/qding-scc-front/index.html这通常就是前端页面入口。十、try_files是什么意思try_files $uri $uri/ /qding-scc-front/index.html;这是前端单页应用里最关键的一句配置之一。它的意思可以理解成先尝试按请求路径找文件找不到就再尝试按目录找还找不到就返回/qding-scc-front/index.html为什么前端必须关心这句因为 Vue、React 这类项目通常有前端路由。比如你前端页面中定义了路由/qding-scc-front/user/list浏览器打开这个地址时Nginx 会先尝试找真实文件/usr/share/nginx/html/qding-scc-front/user/list但这个文件通常并不存在。如果没有try_filesNginx 就会直接报 404。而单页应用的正确逻辑是不管你访问/user/list还是/order/detail最终都先返回同一个index.html再由前端 JavaScript 路由接管页面渲染实际例子 3访问前端路由页面浏览器请求http://192.168.251.6/qding-scc-front/user/listNginx 的处理流程如下前端路由磁盘目录Nginx浏览器前端路由磁盘目录Nginx浏览器请求 /qding-scc-front/user/list查找真实文件 /usr/share/nginx/html/qding-scc-front/user/list文件不存在返回 /usr/share/nginx/html/qding-scc-front/index.html返回 index.html返回 index.html前端路由解析 /user/list渲染“用户列表”页面这就是try_files在前端项目里最典型的用途。十一、proxy_pass是什么意思location /api/qding/ { proxy_pass http://127.0.0.1:8162/; }proxy_pass的意思是把请求转发给另一个服务。在这里就是把请求转发给本机8162端口上的 Java 后端服务。实际例子 4访问后端接口浏览器请求http://192.168.251.6/api/qding/user/listNginx 不会去磁盘找文件而是会把请求转发到http://127.0.0.1:8162/user/list也就是说浏览器以为自己访问的是 Nginx实际处理接口的是后端 Java 服务时序图如下后端8162Nginx浏览器后端8162Nginx浏览器GET /api/qding/user/list转发到 http://127.0.0.1:8162/user/list返回 JSON 数据返回接口响应十二、一个服务器部署多个前端、多个后端时怎么配这也是实际生产里更常见的情况。假设前端项目/qding-scc-front//order-front//user-front/后端服务/api/qding/-8162/api/order/-8163/api/user/-8164那配置可以写成server { listen 80; server_name _; location /qding-scc-front/ { alias /usr/share/nginx/html/qding-scc-front/; index index.html; try_files $uri $uri/ /qding-scc-front/index.html; } location /order-front/ { alias /usr/share/nginx/html/order-front/; index index.html; try_files $uri $uri/ /order-front/index.html; } location /user-front/ { alias /usr/share/nginx/html/user-front/; index index.html; try_files $uri $uri/ /user-front/index.html; } location /api/qding/ { proxy_pass http://127.0.0.1:8162/; } location /api/order/ { proxy_pass http://127.0.0.1:8163/; } location /api/user/ { proxy_pass http://127.0.0.1:8164/; } }这时 Nginx 就像一个统一入口访问不同前端路径返回不同静态站点访问不同接口路径转发到不同后端服务十三、HTTPS、HTTP/2、gzip 又是干什么的除了路由和转发Nginx 还经常承担两个重要职责HTTPS 安全访问前端静态资源传输优化例如下面这些配置listen 443 ssl http2; server_name iam-uat.cscec1b.net; ssl_certificate /etc/nginx/ssl/iam-uat.cscec1b.net.pem; ssl_certificate_key /etc/nginx/ssl/iam-uat.cscec1b.net-key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; gzip on; gzip_min_length 1k; gzip_comp_level 6; gzip_types text/plain text/css text/javascript application/javascript application/json image/svgxml; gzip_vary on;1.listen 443 ssl http2;表示这个站点开启443HTTPS 默认端口ssl启用 HTTPS 加密http2启用更高效的 HTTP/2 协议实际意义浏览器访问的是https://...页面资源传输更安全多个 JS/CSS 文件加载更高效2.ssl_certificate和ssl_certificate_key表示 HTTPS 证书和私钥的位置。没有这两个HTTPS 就跑不起来。3.ssl_protocols TLSv1.2 TLSv1.3;表示只允许较新的安全协议禁掉老旧不安全协议。4.gzip on;表示开启压缩。这对前端特别有意义因为前端项目通常会返回JSCSSJSONSVG这些文件压缩后能明显减小体积页面加载更快。一个很直观的例子比如一个前端页面首次加载会请求main.js2MBvendor.js3MBapp.css300KB如果不开gzip这些文件会原样传输。如果开了gzip很多文本资源体积会明显下降用户打开页面时速度通常会更好。十四、一个适合业务拆分的推荐配置思路如果是长期维护的环境我更推荐nginx.conf只放全局配置比如eventshttp日志格式gzipssl_protocolsinclude /etc/nginx/conf.d/*.conf/etc/nginx/conf.d/app-routes.conf专门放业务站点和接口路由比如server { listen 80; server_name _; location /qding-scc-front/ { alias /usr/share/nginx/html/qding-scc-front/; index index.html; try_files $uri $uri/ /qding-scc-front/index.html; } location /order-front/ { alias /usr/share/nginx/html/order-front/; index index.html; try_files $uri $uri/ /order-front/index.html; } location /api/qding/ { proxy_pass http://127.0.0.1:8162/; } location /api/order/ { proxy_pass http://127.0.0.1:8163/; } }这样做的好处是全局和业务分离配置结构更清楚以后新增前端或后端时更方便十五、我对 Nginx 前端部署的理解总结这次把前端部署这块理顺之后我对 Nginx 的理解比以前清晰了很多。我现在会把它看成一个统一入口它主要在做这些事情根据 URL 路径匹配location把前端路径映射到真实静态文件目录把单页应用路由回退到index.html把接口请求转发给后端服务通过 HTTPS 提供安全访问通过 gzip 和 HTTP/2 优化前端资源传输如果只用一句话总结Nginx 不只是“放前端页面的地方”更是前端静态资源服务、接口转发、安全接入和性能优化的统一入口。十六、文末速记版location匹配某类 URL 请求怎么处理alias把 URL 路径映射到真实磁盘目录index访问目录时默认返回哪个首页文件try_files按顺序尝试找文件找不到就回退到指定文件proxy_pass把请求转发给后端服务listen 443 ssl http2开启 HTTPS 和 HTTP/2gzip压缩前端静态资源和 JSON 响应减少传输体积

相关新闻