nginx前后端分离核心是用location区分静态资源与/api请求:/块托管前端文件并支持history模式,/api/块代理至后端;proxy_pass末尾斜杠决定路径是否剥离,需匹配后端路由;必须透传host、x-real-ip等真实请求头,并可配置cors响应头解决跨域。

用 Nginx 的 location 实现前后端分离,核心是把静态资源请求和 API 请求分开处理:前端 HTML/JS/CSS 由 Nginx 直接返回,所有 /api/ 开头的请求则转发给后端服务。这不是加几个配置就能跑通的事,关键在路径匹配逻辑、proxy_pass 斜杠行为、以及真实请求头的透传。
区分两类请求:静态资源走本地,API 走代理
前端打包后的文件(如 index.html、app.js)放在服务器某个目录(比如 /var/www/frontend/dist),Nginx 直接提供服务;而后端接口运行在 http://127.0.0.1:3000 或其他地址,不对外暴露端口。
-
location /块负责托管前端静态文件,配合root和try_files支持 Vue/React 的 history 模式 -
location /api/块专门捕获接口请求,用proxy_pass转发到后端 - 避免用
location ~ \.js$这类正则干扰主流程,静态资源优先走前缀匹配
proxy_pass 末尾斜杠决定路径是否被剥离
这是最容易出错的地方。假设客户端请求 https://example.com/api/users:
- 写成
proxy_pass http://127.0.0.1:3000;(无斜杠)→ 后端收到完整路径/api/users - 写成
proxy_pass http://127.0.0.1:3000/;(有斜杠)→ Nginx 自动去掉/api/,后端只收到/users
选哪种取决于后端路由设计。若后端接口定义为 GET /users,就用带斜杠写法;若定义为 GET /api/users,就用不带斜杠写法。
必须透传客户端真实信息
后端如果要做 IP 限流、日志记录或地理位置识别,不能只看到 Nginx 的内网 IP。需在 location /api/ 块中显式设置:
-
proxy_set_header Host $host;—— 保留原始 Host,方便后端生成正确跳转链接 -
proxy_set_header X-Real-IP $remote_addr;—— 最直接的客户端 IP -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;—— 支持多层代理链
顺手解决跨域问题
既然所有请求都经过 Nginx 入口,浏览器眼里前后端就是同源,根本不会触发跨域检查。但有些场景仍需兼容直连调试或第三方调用,可在 location /api/ 中加响应头:
add_header Access-Control-Allow-Origin "https://your-frontend.com" always;add_header Access-Control-Allow-Credentials "true" always;add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;- 对
OPTIONS预检请求单独处理,返回 204 并终止后续代理:if ($request_method = 'OPTIONS') { add_header Access-Control-Max-Age 1728000; add_header Content-Type 'text/plain; charset=UTF-8'; return 204; }











