【Java后端】【nginx】nginx配置重定向问题记录

📅 发布时间:2026/7/12 1:31:02 👁️ 浏览次数:
【Java后端】【nginx】nginx配置重定向问题记录
Nginx 子路径部署 React SPA 踩坑总结背景将 React 单页应用SPA部署在 Nginx 子路径/company/、/company-admin/下与个人博客/共用同一台服务器过程中遇到了三个典型问题。问题一aliastry_files回退路径错误现象刷新页面如/company/products或直接访问子路由时返回 404 或跳转到根路径。错误配置location /company/ { alias /var/www/company-font/; index index.html; try_files $uri $uri/ /company/index.html; # ❌ 错误 }根因在alias块中try_files的回退路径/company/index.html是相对于全局root如/var/www/personal-website解析的而不是alias指定的目录。该路径不存在导致 Nginx 触发异常跳转。正确配置location /company/ { alias /var/www/company-font/; index index.html; try_files $uri $uri/ /var/www/company-font/index.html; # ✅ 使用绝对路径 }结论在alias块中try_files的 fallback 必须使用文件系统绝对路径。问题二无尾斜杠路径/company被错误路由现象访问http://example.com/company无尾斜杠时返回了个人博客首页而不是企业官网。根因Nginx 的location /company/带尾斜杠不匹配/company无尾斜杠请求该请求被location /兜底处理返回了/var/www/personal-website/index.html。修复新增精确匹配 location将无尾斜杠请求 301 重定向到有尾斜杠路径location /company { return 301 /company/; } location /company-admin { return 301 /company-admin/; }问题三React 登录后navigate(/)跳出子路径现象用户登录成功后页面跳转到了http://example.com/而不是http://example.com/company/。根因分析React Router v6 中BrowserRouter设置了basename/companynavigate(/)理论上会跳转到/company/。但实际触发跳出的原因是旧代码在navigate(/)之后紧接着调用了window.location.reload()navigate是异步的reload()在路由未完成切换时执行此时 URL 还在/company/loginreload 触发浏览器刷新命中了上述问题二/company无斜杠被个人博客兜底最终落到了根路径修复移除window.location.reload()改用navigate的replace选项// ❌ 旧代码navigate(/);window.location.reload();// ✅ 新代码navigate(/,{replace:true});问题四登录后 Navbar 状态不同步现象登录成功跳转回首页后Navbar 仍然显示登录/注册按钮没有变成用户信息。根因Navbar 组件读取登录状态的useEffect依赖数组为空只在组件挂载时执行一次。登录操作在 Login 组件中完成写入 localStorage 后 Navbar 不会感知到变化。// ❌ 问题代码只在挂载时读一次useEffect((){setLoggedIn(isAuthenticated());setUser(getUser());},[]);修复登录时派发自定义事件Navbar 监听该事件刷新状态Login.jsxsetToken(data.token);setUser({username,nickname,role});window.dispatchEvent(newEvent(auth-change));// 通知 Navbarnavigate(/,{replace:true});Navbar.jsxconstrefreshAuthuseCallback((){setLoggedIn(isAuthenticated());setUser(getUser());},[]);useEffect((){refreshAuth();window.addEventListener(auth-change,refreshAuth);return()window.removeEventListener(auth-change,refreshAuth);},[refreshAuth]);最终完整 Nginx 配置server { listen 80; server_name _; root /var/www/personal-website; index index.html; client_max_body_size 20m; # 无尾斜杠重定向防止被 location / 兜底 location /company { return 301 /company/; } location /company-admin { return 301 /company-admin/; } # 个人博客根路径 location / { try_files $uri $uri/ /index.html; } # 企业官网前端 location /company/ { alias /var/www/company-font/; index index.html; try_files $uri $uri/ /var/www/company-font/index.html; } # 管理后台前端 location /company-admin/ { alias /var/www/company-admin/; index index.html; try_files $uri $uri/ /var/www/company-admin/index.html; } # 后端 API去掉前缀后转发 location /company-api/ { rewrite ^/company-api/(.*)$ /api/$1 break; proxy_pass http://127.0.0.1:9080; 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; } }总结问题根因修复要点alias try_files 404fallback 路径相对于 root 解析使用文件系统绝对路径无尾斜杠被根路径兜底location /company/不匹配/company新增location /company做 301 跳转登录后跳出子路径window.location.reload()与异步 navigate 竞争移除 reload用navigate(/, { replace: true })登录后 Navbar 不更新useEffect 空依赖只执行一次自定义事件auth-change跨组件通知