路由知识点总结
程序员文章站
2022-03-10 18:12:29
...
今天看了到一篇关于100道前端面试题的文章,看完的感悟是,我太菜了。。。自己学的东西都太基础了,然而这些基础的知识掌握的也不够扎实。。。难受的一批,现在开始一点一点积累吧。
一、前端路由跳转基本原理
1、什么是路由
- 路由是根据不同的url地址来显示不同的页面或内容的功能,这个概念很早是由后端提出的。
后端之前是这么做的,当我们访问 http://xxx.abc.com/xx 的时候,大致流程可以想象成这样的:
- 浏览器向服务器发出请求。
- 服务器监听到80端口,如果有请求过来,那么就解析url地址。
- 服务器根据客户端的路由配置,然后就返回相应的信息(比如html字符串、json数据或图片等)。
- 浏览器根据数据包的 Content-Type来决定如何解析数据。
- 如上就是后端路由最初始的实现方式,那么既然有后端路由,那为什么还需要我们前端路由呢?后端路由有一个很大的 缺点就是每次路由切换的时候都需要去刷新页面,然后发出ajax请求,然后将请求数据返回回来,存在一定的延迟,那么这样每次路由切换都要刷新页面对于用户体验来说就不好了。 因此为了提升用户体验,我们前端路由就这样产生了。它就可以解决浏览器不会重新刷新了。
- 目前前端路由方案主要有以下几种:
(1)hash:可能是大多数人了解的模式,主要是基于锚点的原理实现。简单易用
(2)browser/history:即使用html5标准中的history api通过监听popstate事件来对dom进行操作。每次路由变化都会引起重定向
(3)memory:这种实现是在内存中维护一个堆栈用于管理访问历史的方式,比较复杂。在早起移动端使用比较多。实现麻烦,问题也较多。现在很少有使用。RN在使用这种路由模式
(4)static:主要用于ssr。需要后端去管理路由
2、hash路由
-
特点: 有带#号,后面就是hash值的变化。改变后面的hash值,它不会向服务器发出请求,因此也就不会刷新页面。并且每次hash值发生改变的时候,会触发hashchange事件。通过监听该事件,来知道hash值发生了哪些变化。比如我们可以如下简单的监听:
function hashAndUpdate () { // todo 匹配 hash 做 dom 更新操作 } window.addEventListener('hashchange', hashAndUpdate);
-
相关API:
location.href // 完整的url ,改变会刷新页面 location.protocol // 当前URL的协议,包括 :; 比如 https: location.host //* 主机名和端口号,如果端口号是80(http)或443(https), 那就会省略端口号,比兔 www.baidu.com:8080 */ location.hostname // 主机名:比如:www.baidu.com location.port // 端口号;比如8080 location.pathname // url的路径部分,从 / 开始; 比如 https://www.baidu.com/s?ie=utf-8,那么 pathname = '/s'了 location.search // 查询参数,从?开始;比如 https://www.baidu.com/s?ie=utf-8 那么 search = '?ie=utf-8' location.hash // 改变不会刷新页面,hash是页面中的一个片段,从 # 开始的,比如 https://www.baidu.com/#/a/b 那么返回值就是:"#/a/b"
-
优缺点:
- 优点
1.实现简单,兼容性好(兼容到ie8)
2.绝大多数前端框架均提供了给予hash的路由实现
3.不需要服务器端进行任何设置和开发
4.除了资源加载和ajax请求以外,不会发起其他请求 - 缺点
1.对于部分需要重定向的操作,后端无法获取hash部分内容,导致后台无法取得url中的数据,典型的例子就是微信公众号的oauth验证
2.服务器端无法准确跟踪前端路由信息
3.对于需要锚点功能的需求会与目前路由机制冲突
- 优点
3、history路由
-
特点:可以在同源下其他路径跳转,优于#路由,可以操作路径也可以操作hash,但是兼容不好
-
相关API:
history.go(n) //路由跳转,比如n为 2 是往前移动2个页面,n为 -2 是向后移动2个页面,n为0是刷新页面 history.back() //路由后退,相当于 history.go(-1) history.forward() //路由前进,相当于 history.go(1) history.pushState() //添加一条路由历史记录,如果设置跨域网址则报错 history.replaceState() //替换当前页在路由历史记录的信息 popstate //事件:当活动的历史记录发生变化,就会触发 popstate 事件,在点击浏览器的前进后退按钮或者调用上面前三个方法的时候也会触发,
-
HTML5 history新增了两个API:
history.pushState
和history.replaceState
-
两个API都接收三个参数:
- 状态对象(state object):一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
- 标题(title):FireFox浏览器目前会忽略该参数,虽然以后可能会用上。考虑到未来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也可以传入一个简短的标题,标明将要进入的状态。
- 地址(URL): 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但之后,可能会试图加载,例如用户重启浏览器。新的URL不一定是绝对路径;如果是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,否则,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。
-
二者差异
- 相同之处是两个API都会操作浏览器的历史记录,而不会引起页面的刷新。
- 不同之处在于pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录。
-
history路由优缺点:
- 优点
1.对于重定向过程中不会丢失url中的参数。后端可以拿到这部分数据
2.绝大多数前段框架均提供了browser的路由实现
3.后端可以准确跟踪路由信息
4.可以使用history.state来获取当前url对应的状态信息 - 缺点
1.兼容性不如hash路由(只兼容到IE10)
2.需要后端支持,每次返回html文档
- 优点
4、memory路由
- 特点:这种实现是在内存中维护一个堆栈用于管理访问历史的方式,比较复杂。在早起移动端使用比较多。实现麻烦,问题也较多。现在很少有使用。RN在使用这种路由模式
- 优缺点:
- 优点
不存在兼容性问题,路由保存在内存中
不需要服务器端提供支持 - 缺点
目前很少有前端路由模块提供对memory路由的实现(react-router提供了memory实现)
自己实现难度较大,且工作量也很大
对于前进后退操作的路由管理非常麻烦,尤其是android设备的backbutton
- 优点
5、hash路由和history的区别
- Hash 模式是使用 URL 的 Hash 来模拟一个完整的 URL,因此当 URL 改变的时候页面并不会重载。
- History 模式则会直接改变 URL,所以在路由跳转的时候会丢失一些地址信息,在刷新或直接访问路由地址的时候会匹配不到静态资源。因此需要在服务器上配置一些信息,让服务器增加一个覆盖所有情况的候选资源,比如跳转 index.html 什么的,一般来说是你的 app 依赖的页面。
6、三者路由适用场景
-
hash模式适用场景:
1.兼容IE8
2.没有重定向传参需求(第三方认证oauth)
3.没有锚点跳跃需求
4.后端不需要跟踪前端路由信息 -
history模式适用场景:
1.页面内锚点需求
2.需要重定向传参
3.同构直出
4.后端跟踪路由信息
5.附加路由信息(history.state)获取路由状态 -
memory模式适用场景:
1.ie8以下兼容
2.React Native
总结了这篇blog,希望对自己和对大家都有帮助,如果有哪里写错了,欢迎大佬指点。
下一篇: 什么是MTU?