介绍
在开发中我们在使用react官方推荐的react-router的BrowserRouter时候,如果不做特殊处理,当跳转路由之后,刷新浏览器一定会报404的问题。
出现问题的原因
browserHistory 模式下,URL 是指向真实 URL 的资源路径,当通过真实 URL 访问网站的时候(首页),这个时候可以正常加载我们的网站资源,而用户在非首页下手动刷新网页时,由于路径是指向服务器的真实路径,但该路径下并没有相关资源,用户访问的资源不存在,返回给用户的是 404 错误
解决
原理就是在刷新浏览器的时候,重新将当前路径下请求的资源全部指向SPA的index.html
开发模式
通过webpack-dev-server
的historyApiFallback
来进行解决。
{
devServer: {
open: false,
port: 3000,
hotOnly: true,
host: 'localhost',
contentBase: path.join(PROJECT_PATH, 'dist'),
stats: {
modules: false,
asset: false,
},
clientLogLevel: 'silent',
// noInfo: true,
historyApiFallback: true, // 解决BrowserRouter路由跳转之后刷新浏览器按钮报404的情况
}
}
线上部署
node服务器
const path = require('path');
const history = require('connect-history-api-fallback');
const express = require('express');
const app = express();
app.use(history()); // 注册处理前端采用history模式的路由
app.use(express.static(path.join(__dirname,'../web'))); // 前端静态资源所在的目录
app.listen(8070,()=>{
console.log("开启了一个node服务,端口号为8070")
})
nginx服务器
server {
...,
location / {
root /Users/website/dist; # 前端静态文件在服务器上的绝对路径
index index.html index.htm;
try_files $uri $uri/ /index.html; # 当按照浏览器路径找不到资源的时候,重新尝试寻找$uri(就是root 对应的路径) 路径下的index.html
}
}
react嵌套路由(分组路由)解决方式
在使用嵌套路由或者分组路由的时候,有的时候会发现按照以上两种方案并不能解决问题,刷新浏览器仍然会有问题出现。这个时候就要去看webpack打包出来的index.html中对js的引用方式,必须是/
开头,不能是./
开头。
解决方式:
{
new HtmlWebpackPlugin({
template: path.join(PROJECT_PATH, 'public/index.html'),
filename: 'index.html',
publicPath: '/', // 确保引用js资源的路径是以’/‘ 开头的
}),
}