You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

S3 Bucket无法部署含react-router-dom的React应用问题排查

React单页应用S3托管+Nginx反向代理路由问题排查与解决

问题背景

基于React开发的单页应用,部署架构为:EC2实例部署Nginx,通过proxy_pass配置指向存储构建文件(含index.html)的S3 Bucket,使用GitLab CI/CD自动化构建部署。遇到以下问题:

  • 访问域名时,S3无法正常返回index.html和/signin页面
  • 将构建文件直接上传至EC2本地目录,Nginx指向本地文件时,应用可正常运行并路由
  • 已配置S3静态网站托管,将index.html设为错误页面以适配SPA路由,但非首页请求仍无法触发index.html作为入口
  • 调整Bucket权限与属性后,访问域名仍显示空白页;直接访问Bucket内的index.html,仅显示路由外的footer组件

核心代码(App.js)

import React from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import SignIn from './SignIn';

function App() {
  return (
      <Router>
        <div className="container">
          <Routes>
            <Route exact path="/" element={
              <div className="content">
                <img src="/logo.png" alt="Logo" className="logo" />
                <h1>Website Under Construction</h1>
                <p>We're working hard to bring you a great experience. Stay tuned!</p>
              </div>
            } />
            <Route path="/signin" element={<SignIn />} />
          </Routes>
          <footer className="footer">
            <p>&copy; {new Date().getFullYear()} . All rights reserved.</p>
          </footer>
        </div>
      </Router>
  );
}
export default App;

问题原因分析

  1. Nginx代理S3对象存储的局限性:S3静态网站托管的错误页面重定向规则,仅在直接访问S3静态网站域名时生效。若通过Nginxproxy_pass指向S3对象存储域名(如xxx.s3.amazonaws.com),S3会直接按路径查找对象,找不到则返回404,不会触发错误页面重定向。
  2. 资源路径与访问方式不匹配:直接访问Bucket内index.html仅显示footer,说明React路由未正确初始化。原因是构建文件中静态资源(JS/CSS)使用绝对路径,而Nginx代理到S3时,资源请求路径未匹配S3内的对象存储路径,导致资源加载失败,路由无法初始化。
  3. S3对象元数据或权限问题:若index.html的Content-Type未设为text/html,或Bucket访问策略未允许Nginx所在EC2(或公网)读取对象,会导致页面无法正常解析或加载。

解决方案

方案一:调整Nginx配置,主动处理SPA路由

让Nginx先拦截所有路由请求,统一转发到S3的index.html,静态资源直接转发到S3对应路径:

server {
    listen 80;
    server_name your-domain.com;

    # 转发静态资源请求到S3
    location ~* \.(js|css|png|jpg|svg)$ {
        proxy_pass https://your-bucket.s3.amazonaws.com;
        proxy_set_header Host your-bucket.s3.amazonaws.com;
        proxy_cache_bypass $http_upgrade;
    }

    # 所有路由请求返回S3的index.html
    location / {
        proxy_pass https://your-bucket.s3.amazonaws.com/index.html;
        proxy_set_header Host your-bucket.s3.amazonaws.com;
        proxy_set_header Accept-Encoding "";
    }
}

注意:需确保S3 Bucket策略允许Nginx所在EC2的IP访问,或开启公网可读并配置正确CORS

方案二:代理S3静态网站托管域名

改用S3静态网站托管的专属域名(如your-bucket.s3-website-us-east-1.amazonaws.com)作为代理目标,此时S3的错误页面重定向规则会生效:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://your-bucket.s3-website-us-east-1.amazonaws.com;
        proxy_set_header Host your-bucket.s3-website-us-east-1.amazonaws.com;
        proxy_redirect off;
    }
}

方案三:EC2本地托管构建文件

直接将构建文件部署到EC2本地,Nginx直接指向本地文件并配置SPA路由规则,避免S3代理的兼容性问题:

server {
    listen 80;
    server_name your-domain.com;

    root /path/to/react/build;
    index index.html;

    # 静态资源设置缓存
    location ~* \.(js|css|png|jpg|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # 所有路由请求返回index.html
    location / {
        try_files $uri $uri/ /index.html;
    }
}

补充配置要点

  • 检查S3中index.html的Content-Type是否为text/html,静态资源的Content-Type是否正确(如JS设为application/javascript)
  • 配置S3 Bucket的CORS策略,允许域名的跨域请求(若需前端直接调用S3资源)
  • 查看Nginx错误日志(/var/log/nginx/error.log),定位具体的404或权限错误

内容的提问来源于stack exchange,提问作者Sunith Christopher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 20:57:05