ReactJS中react-router动态路由开发正常生产环境刷新报错问题
问题原因
- 静态资源路径配置错误:项目内静态资源(图片、编译后的js/css文件等)使用相对路径引入,当访问多级动态路由如
/activity/123时,浏览器会基于当前路由路径拼接资源地址,比如原路径./static/js/main.xxxx.js会被拼接为/activity/static/js/main.xxxx.js,服务器不存在对应资源就会加载失败。 - Browser路由服务端适配缺失:你使用的是react-router的
BrowserRouter,依赖H5 History API实现前端路由,开发环境的dev-server默认配置了所有请求 fallback 到index.html,因此刷新正常。但生产环境的静态服务未做对应配置,刷新时浏览器会直接向服务器请求/activity/123路径,服务器找不到对应文件就返回错误内容,导致页面空白。
解决方案
1. 修复静态资源路径
修改React项目package.json中的homepage字段,设置为绝对路径:
如果部署在域名根路径,配置为:
"homepage": "/"
如果部署在子路径,填写对应子路径即可,例如"homepage": "/my-app/"。
同时静态资源引入优先使用绝对路径,或者用process.env.PUBLIC_URL拼接,比如图片引入示例:
<img src={`${process.env.PUBLIC_URL}/images/logo.png`} alt="logo" />
2. 配置静态服务支持路由 fallback
如果使用serve启动生产服务,启动时添加-s参数开启单页应用模式,所有请求会自动fallback到index.html:
serve -s build
如果使用Nginx部署,修改Nginx配置的location块,添加try_files规则:
location / { root /usr/share/nginx/html; index index.html index.htm; # 核心配置:所有找不到的请求都返回index.html,交给前端路由处理 try_files $uri $uri/ /index.html; }
如果使用Apache部署,在项目public目录下新建.htaccess文件,写入以下规则:
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] </IfModule>
如果不想修改服务端配置,也可以将BrowserRouter替换为HashRouter,使用哈希模式实现路由,无需服务端额外配置,缺点是URL中会携带#符号。
内容的提问来源于stack exchange,提问作者Gan Mongklakorn
相关产品推荐
相关产品推荐

