一、问题/场景描述
在使用React开发单页应用(SPA)时,当用户直接访问某个路由路径(如 /user/profile),或者刷新浏览器页面时,经常遇到页面空白或显示“404 Not Found”错误。这个问题通常发生在生产环境部署后,本地开发环境(通过webpack-dev-server)可能正常,但部署到Nginx、Apache等服务器上就会触发404。这导致用户体验极差,且难以排查。
二、原因分析
React路由(如React Router v6)是基于浏览器端JavaScript实现的,所有路由切换都在客户端完成。当用户直接输入URL或刷新页面时,浏览器会向服务器发送HTTP请求。如果服务器没有针对这些路径配置重写规则,就会按照常规静态文件请求处理,结果找不到对应的文件,返回404状态码。
核心问题在于:React应用的入口文件是 index.html,所有路由路径都应由这个HTML文件处理,但服务器默认只会响应根路径 / 的请求。因此,需要配置服务器将所有非静态资源请求(如 /about、/login)都指向 index.html,由React Router在客户端解析路由。
三、详细解决步骤
步骤1:确认构建输出结构
首先确保React项目已正确构建。运行构建命令:
npm run build
构建完成后,查看 build 或 dist 目录,应包含 index.html、JavaScript和CSS文件。例如:
ls -la build/
步骤2:配置Nginx服务器
如果使用Nginx作为Web服务器,编辑Nginx配置文件(通常位于 /etc/nginx/sites-available/your-site 或 /etc/nginx/conf.d/)。添加以下 try_files 指令:
server {
listen 80;
server_name your-domain.com;
root /path/to/your/react-app/build;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# 可选:静态资源缓存优化
location ~* .(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
关键行是 try_files $uri $uri/ /index.html;,它会先尝试匹配请求的文件或目录,如果不存在则返回 index.html。
测试配置并重启Nginx:
sudo nginx -t
sudo systemctl restart nginx
步骤3:配置Apache服务器
如果使用Apache,需要启用 mod_rewrite 模块,并在项目根目录创建 .htaccess 文件:
sudo a2enmod rewrite
RewriteEngine On
RewriteBase /
RewriteRule ^index.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
重启Apache:
sudo systemctl restart apache2
步骤4:配置React Router的Hash模式(备选方案)
如果无法修改服务器配置,可以使用React Router的Hash模式,URL中会包含 # 符号。例如 /#/about。修改路由配置:
import { HashRouter } from 'react-router-dom';
function App() {
return (
<HashRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</HashRouter>
);
}
Hash模式不需要服务器配置,但URL不美观,且对SEO不友好。
步骤5:验证解决方案
部署后,在浏览器中直接访问 http://your-domain.com/about 或任何定义的路由路径,应能正常渲染页面,不再出现404错误。
四、注意事项
1. 确保服务器配置中的 root 路径指向正确的构建输出目录(如 build 或 dist)。
2. 配置 try_files 后,如果遇到路由嵌套或参数路径,仍需正常处理,因为所有请求都指向 index.html。
3. 对于使用React Router v6的项目,BrowserRouter(非Hash模式)是推荐方案,但必须配合服务器重写规则。
4. 如果同时使用API代理,确保API路由不被 index.html 重写覆盖,可单独配置 location /api 块。
五、适用环境
本文适用于 React 18 + React Router v6 + Nginx 1.18+/Apache 2.4+ 环境,构建工具为 Create React App 或 Vite。
