前言:网络上,很多介绍前端路由实现的文章,以及路由原理的文章。但是最近在面试过程中,我发现,所有面试者都能讲清楚路由的技术实现,但是却对每一种技术实现的适用场景不理解。比如
hash
路由,很多人的回答是hash
路由会带有一个#
号不好看,所以用了history
路由。甚至我出去面试的时候,也有一些面试官这么认为(T_T)。任何技术方案的产生都是为了解决某些特定问题的。hash
和history
也不例外。
目前前端路由方案主要有以下几种
hash
:可能是大多数人了解的模式,主要是基于锚点的原理实现。简单易用browser
:即使用html5
标准中的history api
通过监听popstate
事件来对dom
进行操作。每次路由变化都会引起重定向memory
:这种实现是在内存中维护一个堆栈用于管理访问历史的方式,比较复杂。在早起移动端使用比较多。实现麻烦,问题也较多。现在很少有使用。RN
在使用这种路由模式static
:主要用于ssr
。需要后端去管理路由
前端路由解决的问题
- 根据路由变化显示不同的页面,完成页面切换
- 通过
query
传参
前端路由各种实现方案的对比
hash路由 优缺点
-
优点
- 实现简单,兼容性好(兼容到
ie8
) - 绝大多数前端框架均提供了给予
hash
的路由实现 - 不需要服务器端进行任何设置和开发
- 除了资源加载和
ajax
请求以外,不会发起其他请求
- 实现简单,兼容性好(兼容到
-
缺点
- 对于部分需要重定向的操作,后端无法获取
hash
部分内容,导致后台无法取得url
中的数据,典型的例子就是微信公众号的oauth
验证 - 服务器端无法准确跟踪前端路由信息
- 对于需要锚点功能的需求会与目前路由机制冲突
- 对于部分需要重定向的操作,后端无法获取
browser路由 优缺点
-
优点
- 对于重定向过程中不会丢失
url
中的参数。后端可以拿到这部分数据 - 绝大多数前段框架均提供了
browser
的路由实现 - 后端可以准确跟踪路由信息
- 可以使用
history.state
来获取当前url
对应的状态信息
- 对于重定向过程中不会丢失
-
缺点
- 兼容性不如
hash
路由(只兼容到IE10
) - 需要后端支持,每次返回
html
文档
- 兼容性不如
memory路由 优缺点
-
优点
- 不存在兼容性问题,路由保存在内存中
- 不需要服务器端提供支持
-
缺点
- 目前很少有前端路由模块提供对
memory
路由的实现(react-router
提供了memory
实现) - 自己实现难度较大,且工作量也很大
- 对于前进后退操作的路由管理非常麻烦,尤其是
android
设备的backbutton
- 目前很少有前端路由模块提供对
static
路由 优缺点(该路由方式主要用于ssr
。不做比较。)
如何选择合适的前端路由方案?以下建议作为参考:
hash模式适用场景:
- 兼容IE8
- 没有重定向传参需求(第三方认证
oauth
) - 没有锚点跳跃需求
- 后端不需要跟踪前端路由信息
hybrid app
需要将前端资源打包在应用内,因为html
的域在file://
下,所以不能发生重定向
history模式适用场景:
- 页面内锚点需求
- 需要重定向传参
- 同构直出
- 后端跟踪路由信息
- 附加路由信息(
history.state
)获取路由状态
memory模式适用场景:
- ie8以下兼容
- React Native