前端框架

BrowserRouter vs HashRouter

碰到的问题

​ 最近将项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, replaceState and the popstate event) 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

图: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,后面就交给前端路由来实现无刷新加载对应页面。

更多参考文章:

?《react传值》

?《什么是前端路由》

?《router常见用法》

Tagged

发表评论

邮箱地址不会被公开。 必填项已用*标注