碰到的问题
最近将项react项目打包成app的时候,或者说先经历一个npm run build命令打包后,发现将打包后的index.html打开一片空白!!Σ(っ °Д °;)っ我打开浏览器开发工具检查页面元素情况,发现APP组件已经挂载到页面最外层div上了,但是APP组件里什么也没有。我在想,APP组件里放的其实都是路由组件,这就说明了路由组件出问题了,没有被渲染出来。
我刚好百度搜 “为何打包react项目后,打开打包好的页面,是一片空白?” 时看见一个解决方案:将BrowserRouter改为HashRouter。我试着修改并重新打包,页面立马就出来了!不过,这两个路由有什么具体区别我是不太了解的,为什么可以这样修改,可以好好总结一下。
前端路由
首先,为什么需要前端路由这个东西?React是帮助我们开发单页面应用程序的一个框架,其中包含一个index.html文件,每个React Js组件在div元素都在这一个index.html文件中呈现就好了。
从用户角度看,不同URL对应不同的展示页面;对于我们编程开发的,路由就是URL和对应的处理函数的关系。以前,不同的URL与页面的映射,是服务器返回的,现在在前端就可以完成,且只需要一开始请求一次html就好了,后面切换URL的时候就改变部分需要改变的内容即可。(不过有个缺点,就是页面跳转时,你没法儿记住它之前的页面滚动位置库?,每次都回到顶部)。
“Browser Router” or “Hash Router”
React实现路由功能可以用 “Browser Router” or “Hash Router”。
A that uses the HTML5 history API (
pushState,replaceStateand thepopstateevent) to keep your UI in sync with the URL.A that uses the hash portion of the URL (i.e.
window.location.hash) to keep your UI in sync with the URL.
HashRouter
- 基本原理
1.hash 路由变化,onhashchange 事件触发
2.解析路由的地址,匹配要渲染的组件
HistoryRouter
- 基本原理
1.主动触发 h5 history.pushState(state, title, url) API,改变地址栏路由。
2.解析url,匹配要渲染的组件
3.由于state值存在history.state中。所以区别于HashRouter路由传参数,页面刷新参数不会消失。
他俩最直观的区别就是页面地址栏显示的url效果不同,你可以看见一个“#”被附加在HashRouter的URL的结尾处。


图:BroswerRouter 和 HashRouter
第二个应用区别是,如果你将React js编写的应用程序部署到生产服务器后,在生产环境中从一个组件切换到另一个组件。对于BrowserRouter,它使用浏览器中的 History API 处理 URL,它显示的URL 是指向真实 URL 的资源路径。比如说我们从“https://www.qqiuklele.cn/”到“https://www.qqiuklele.cn/blog”,服务器可能去搜索包含HTML文件的blog文件夹了,但并没有对应物理路径/文件,那么服务器可能会抛出一个错误“404:Page Not Found.”。这也是我们看到空白页面的原因。为了表明我们的整个应用程序是在单一页index.html中呈现的,可以使用HashRouter,在主域的末尾附加了“#”,就相当于告诉服务器,HTML代码将在index.html文件中加载。而且这些“#”是不会发送给服务器的,只是起到告知的作用。
解决方式
①改为HashRouter立马见效,但是看文档知道,官方推荐使用BrowserRouter,由于HashRouter没有使用html5中的history API,HashRouter不支持location.key和location.state。
state是router传值的其中一种方式,通过state的方式传值给下一个页面的时候,当到达新的页面,刷新或者后退之后再前进,BrowseRouter传递的值依然可以得到。所以需要知晓如何不影响BrowseRouter的使用。
②采用服务端支持,如nginx,指定目的文件夹和index.html后,也可以用BrowserRouter,这也是我之前使用BroswerRouter并部署到服务器后没有遇到空白页的情况。
server {
server_name react.com;
listen 80;
root /user/src/blog/dist;
index index.html;
location / {
try_files $uri /index.html;
}
}
③除此之外还有:通过修改webpack-dev-server运行方式、Node服务端配置(express或者koa)
详情参考:《React-Router browserHistory浏览器刷新出现页面404解决方案》
其本质的原理就是利用服务端将任何请求都指向
index.html,而在React应用中index.html又刚好通过React-Router配置了相应的路由,我们让服务器返回index.html,后面就交给前端路由来实现无刷新加载对应页面。
更多参考文章:





