单前端适配主/子域名:Nginx与react-router-dom配置问题排查
主域名与子域名路由跳转异常排查(Nginx+React架构)
我正在搭建服务架构,希望通过一个前端应用同时运行主域名sinlessgamesllc.com的网站与子域名helix.sinlessgamesllc.com的Discord机器人面板。当前采用SSL+Nginx部署,搭配Cloudflare DNS、Kemp七层负载均衡及Docker托管,但访问子域名时会跳转至主域名页面,不确定是react-router-dom配置错误还是Nginx配置问题,附当前nginx.conf配置:
server { listen 80; server_name www.sinlessgamesllc.com sinlessgamesllc.com.com; # Redirect all traffic to SSL rewrite ^ https://$server_name$request_uri? permanent; } server { listen 7443 ssl http2 default_server; # enables SSLv3/TLSv1, but not SSLv2 which is weak and should no longer be used. ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.2 TLSv1.3; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; ssl_prefer_server_ciphers on; server_name www.sinlessgamesllc.com sinlessgamesllc.com; ## Access and error logs. access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log info; ## Keep alive timeout set to a greater value for SSL/TLS. keepalive_timeout 75 75; ## See the keepalive_timeout directive in nginx.conf. ## Server certificate and key. ssl on; ssl_certificate /etc/ssl/cert.pem; ssl_certificate_key /etc/ssl/priv.key; ssl_client_certificate /etc/ssl/cloudflare.crt; ## Strict Transport Security header for enhanced security. See ## http://www.chromium.org/sts. I've set it to 2 hours; set it to ## whichever age you want. add_header Strict-Transport-Security "max-age=7200"; root /usr/share/nginx/html; }
问题排查与修复方案
1. Nginx配置核心问题
当前配置存在三个关键问题:
- 未针对子域名
helix.sinlessgamesllc.com配置独立的server块,所有未匹配的请求会落入default_server(主域名的server块),导致显示主域名内容 - 第一个HTTP跳转块的
server_name存在笔误:sinlessgamesllc.com.com应为sinlessgamesllc.com - SSL协议启用了已废弃的
SSLv2和SSLv3,存在安全风险,需移除
修复后的Nginx配置示例
# HTTP到HTTPS通用跳转(匹配所有域名) server { listen 80; server_name _; return 301 https://$host$request_uri; } # 主域名专用server块 server { listen 7443 ssl http2; server_name www.sinlessgamesllc.com sinlessgamesllc.com; access_log /var/log/nginx/main-access.log; error_log /var/log/nginx/main-error.log info; keepalive_timeout 75 75; # 仅启用安全的TLS版本 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; ssl_prefer_server_ciphers on; ssl_certificate /etc/ssl/cert.pem; ssl_certificate_key /etc/ssl/priv.key; ssl_client_certificate /etc/ssl/cloudflare.crt; # 延长HSTS有效期并包含子域名 add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; root /usr/share/nginx/html; # React单页应用路由兼容配置 location / { try_files $uri $uri/ /index.html; } } # 子域名专用server块 server { listen 7443 ssl http2; server_name helix.sinlessgamesllc.com; access_log /var/log/nginx/helix-access.log; error_log /var/log/nginx/helix-error.log info; keepalive_timeout 75 75; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; ssl_prefer_server_ciphers on; ssl_certificate /etc/ssl/cert.pem; # 确保证书包含子域名SAN扩展 ssl_certificate_key /etc/ssl/priv.key; ssl_client_certificate /etc/ssl/cloudflare.crt; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; # 若子域名对应单独的React构建包,指定对应目录 root /usr/share/nginx/helix-html; location / { try_files $uri $uri/ /index.html; } # 若子域名与主域名共用同一React应用,可改用如下配置(需配合React路由判断) # root /usr/share/nginx/html; # location / { # try_files $uri $uri/ /index.html; # } }
2. React-router-dom配置适配
如果主域名和子域名共用同一个React应用,需要在路由逻辑中根据当前域名区分页面:
import { Routes, Route } from 'react-router-dom'; import MainSite from './pages/MainSite'; import HelixPanel from './pages/HelixPanel'; function App() { const isHelixDomain = window.location.hostname === 'helix.sinlessgamesllc.com'; return ( <Routes> {isHelixDomain ? ( <Route path="/*" element={<HelixPanel />} /> ) : ( <Route path="/*" element={<MainSite />} /> )} </Routes> ); } export default App;
3. 额外验证项
- 确认Cloudflare DNS已添加
helix.sinlessgamesllc.com的解析记录,指向Kemp负载均衡节点 - 检查Kemp负载均衡是否保留了请求的
Host头,否则Nginx无法识别子域名 - 验证SSL证书包含子域名的SAN(Subject Alternative Name)字段,避免证书错误
- 清除浏览器缓存,排除旧跳转规则的影响
内容的提问来源于stack exchange,提问作者Tim Pierce
相关产品推荐
相关产品推荐

