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

React Router v6与AWS S3重定向规则适配问题求解

解决AWS S3 + React Router v6移除#!路由前缀的方案

方案一:S3重定向参数 + React客户端处理

  1. 调整S3重定向规则
    替换原有的#!重定向配置,将不存在的请求重定向到/index.html并携带原始路径作为查询参数。在S3静态网站托管的重定向规则中添加以下配置:
[
  {
    "Condition": {
      "HttpErrorCodeReturnedEquals": "404"
    },
    "Redirect": {
      "HostName": "你的S3网站域名",
      "HttpRedirectCode": "302",
      "Protocol": "https",
      "ReplaceKeyWith": "index.html?redirect=$requestURI"
    }
  }
]

此配置会将/about这类404请求重定向到/index.html?redirect=/about,避免自动添加#!前缀。

  1. React客户端处理参数导航
    在<BrowserRouter>包裹的组件内部(保证处于Router上下文),通过useNavigate和useLocation处理查询参数,导航到真实路径:
import { useEffect } from 'react';
import { useNavigate, useLocation, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';

function App() {
  const navigate = useNavigate();
  const location = useLocation();

  useEffect(() => {
    const searchParams = new URLSearchParams(location.search);
    const redirectPath = searchParams.get('redirect');
    if (redirectPath) {
      const cleanPath = redirectPath.startsWith('/') ? redirectPath : `/${redirectPath}`;
      // 用replace模式避免历史记录冗余
      navigate(cleanPath, { replace: true });
    }
  }, [navigate, location.search]);

  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      {/* 其他路由配置 */}
    </Routes>
  );
}

export default App;

确保根组件使用BrowserRouter而非HashRouter:

import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')).render(
  <Router>
    <App />
  </Router>
);
  1. 设置index.html缓存策略
    在S3中给index.html设置缓存控制为no-cache,避免浏览器缓存旧页面导致参数处理失效。

方案二:CloudFront + Lambda@Edge(更优SEO方案)

如果对SEO要求较高,推荐用CloudFront配合Lambda@Edge在服务器端处理路径重写,无需客户端跳转:

  1. 编写Lambda@Edge函数
    创建Node.js函数,识别静态资源请求,将非静态资源请求重写到index.html:
exports.handler = async (event) => {
  const request = event.Records[0].cf.request;
  const uri = request.uri;

  // 匹配静态资源后缀,直接放行
  const staticAssetRegex = /\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf)$/;
  if (staticAssetRegex.test(uri)) {
    return request;
  }

  // 非静态资源请求重写到index.html,保留原始路径供React Router处理
  request.uri = '/index.html';
  return request;
};

注意:Lambda函数需部署在us-east-1区域,才能关联到CloudFront。

  1. 关联Lambda到CloudFront
    在CloudFront控制台中,将上述Lambda函数关联到Viewer Request事件,所有请求到达S3前会先经过Lambda处理。

  2. 更新S3配置
    无需设置S3静态网站托管的错误文档,CloudFront已将非静态资源请求转发到index.html,React Router可以直接处理原始路径,完全避免#!前缀。

此方案无客户端跳转,URL保持干净,对SEO更友好,同时规避了S3错误文档设置带来的潜在SEO风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:43:17