Nginx部署React+Django时/api、/admin路由被React拦截问题
问题根因
这个路由冲突的核心原因是React使用客户端路由(如react-router)实现页面跳转:页面内点击链接跳转时,是浏览器端JS直接操作历史记录和DOM完成的,不会向服务端发起新的文档请求,Nginx配置的/api、/admin转发规则根本不会触发;只有手动硬刷新页面时,浏览器才会主动向服务端请求对应路径的资源,此时Nginx的路由规则才会生效。
解决方案
优先推荐调整Nginx配置解决,这是前后端分离部署的标准方案,不需要侵入业务代码;React侧配置可作为兜底补充。
方案1:修正Nginx配置(推荐)
你当前的根路径配置存在两个问题:一是没有指定React静态资源的存放目录,二是单页应用路由回退规则配置错误。正确的配置逻辑是:
- 优先匹配
/api/、/admin/前缀的请求,直接转发给uWSGI对接Django - 其余请求优先查找对应静态文件(JS/CSS/图片等),找不到静态文件时统一返回React入口文件
index.html,交给客户端路由处理
修正后的配置参考:
# 后端路由规则 location /api/ { uwsgi_pass uwsgi; include /etc/nginx/uwsgi_params; } location /admin/ { uwsgi_pass uwsgi; include /etc/nginx/uwsgi_params; } # 前端路由与静态资源规则 location / { root /your/react/build/path; # 替换为React打包后build文件夹的实际绝对路径 try_files $uri $uri/ /index.html; # 不要配置为=404,否则前端子路径硬刷新会直接返回404错误 }
配置修改完成后,执行nginx -t校验语法无误,再执行nginx -s reload重载配置即可生效。
说明:当前Django侧的路由配置不需要调整,Nginx转发时会携带完整请求路径,
/api/v1/的请求可以正常命中Django的路由规则。
方案2:React侧配置路由兜底(可选)
如果需要在前端做额外防护,可以给React Router添加路由守卫,匹配到/api、/admin开头的路径时,强制触发页面硬跳转,让请求走到Nginx服务端。以react-router v6为例:
import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom'; // 路由守卫组件 function BackendRouteGuard({ children }) { const location = useLocation(); // 匹配后端路径前缀时,强制触发服务端跳转 if (location.pathname.startsWith('/api') || location.pathname.startsWith('/admin')) { window.location.href = location.pathname + location.search; return null; } return children; } function App() { return ( <BrowserRouter> <BackendRouteGuard> <Routes> <Route path="/" element={<HomePage />} /> {/* 其余前端业务路由 */} <Route path="*" element={<NotFoundPage />} /> </Routes> </BackendRouteGuard> </BrowserRouter> ); }
该方案仅作为兜底补充,会产生额外的跳转开销,不建议作为核心解决方案。
内容的提问来源于stack exchange,提问作者Dylan.evans007
相关产品推荐
相关产品推荐

