配置项
devServer.historyApiFallback = true
output.publicPath = "/"
配置流程
react-router 是 React 项目的路由解决方案。
其中有三种路由器 Router,分别为 MemoryRouter, HashRouter 以及本片测试的 BrowserRouter 。
以下为使用流程中的问题及解决。
【暂时写简化版,有空会在过程中截图补上】
- 使用 BrowserRouter 后,点击链接可以正常跳转,但是只要一刷新(当前请求URL非根路径),就会报错404。
即:访问localhost:3000/
可以,刷新也正常。
但访问如localhost:3000/asd
之类的URL,可以点击链接去访问,但刷新后就报404。
解决思路:在服务端做配置(规则设置),当响应状态码为404时,返回页面为index.html
即可。
如何设置?
使用webpack配置时,一般使用webpack-dev-server
作为开发环境的“临时”服务器,即我们要修改这个服务器的规则。
devServer: {
port: 3000,
historyApiFallback: true,
},
官网文档: https://www.webpackjs.com/configuration/dev-server/
这样一来,根URL以及根URL下URL下可访问,可刷新。
但深层次的URL刷新依旧404。
- 深层次目录下刷新,页面无内容,F12分析后发现 app.js 未加载成功。
app.js为什么加载失败?观察请求URL可发现 app.js 前的URL段多了。
即:请求app.js的URL拼接错误。
浏览器查看当前页面发现:
<script src="app.js"></script>
因为程序生成的index.html中,引入app.js的方式是相对路径(当前路径下的app,js)
所以才有深层次URL下刷新就会失败(因为请求本层次下的app.js,当然找不到)。
解决思路:程序生成 index.html 时这样:<script src="/app.js"></script>
虽然只是多了一个/
,但确实从相对路径到绝对路径的转变。
这样即使在任何目录层次,刷新页面请求app.js的路径都是localhost:3000/app.js
。(暂以开发环境为例)
配置webpack输出:
output: {
// ...
publicPath: "/", // 向index.html织入<script>时src的前缀。"app.js"-->"/app.js"
},
官网文档:https://www.webpackjs.com/concepts/output/
后端部署问题
编译好后的index.html + app.js 部署到后端项目的静态文件夹中。
如: SpringBoot 项目的 src/main/resources/statics
中。
就会发现:在非根URL时刷新,页面又404?
原因:
之前开发环境下配置的devServer.historyApiFallback
是webpack-dev-server
的404处理规则。
现在换了新的后端服务(即我们的SpringBoot项目),这个项目也需要配置一些规则:
当响应码Wie404的时候,返回一个指定的页面 index.html
配置方法可参考:SpringBoot 统一配置错误页面 403 404 500