前端路由hash、history原理

本文参考https://www.cnblogs.com/tugenhua0707/p/10859214.html

先来看下后端路由的实现方式:

1. 浏览器向服务器发出请求。
2. 服务器监听到80端口,如果有请求过来,那么就解析url地址。
3. 服务器根据客户端的路由配置,然后就返回相应的信息(比如html字符串、json数据或图片等)。
4. 浏览器根据数据包的 Content-Type来决定如何解析数据。

缺点: 每次路由切换的时候都需要去刷新页面,然后发出ajax请求,然后将请求数据返回回来,那么这样每次路由切换都要刷新页面对于用户体验来说就不好了。因此为了提升用户体验,我们前端路由就这样产生了。它就可以解决浏览器不会重新刷新了。

那么前端路由也有2种模式,第一种是hash模式,第二种是history模式。我们来分别看下这两种知识点及区别如下:

1. hash模式

hash路由模式是这样的:http://xxx.abc.com/#/xx。 有带#号,后面就是hash值的变化。改变后面的hash值,它不会向服务器发出请求,因此也就不会刷新页面。并且每次hash值发生改变的时候,会触发hashchange事件。因此我们可以通过监听该事件,来知道hash值发生了哪些变化。比如我们可以如下简单的监听:

function hashAndUpdate () {
   // todo 匹配 hash 做 dom 更新操作
}

window.addEventListener('hashchange', hashAndUpdate);
// 完整的url
location.href  

// 当前URL的协议,包括 :; 比如 https:     
location.protocol   

/* 主机名和端口号,如果端口号是80(http)或443(https), 那就会省略端口号,比兔 www.baidu.com:8080 */
location.host  

// 主机名:比如:www.baidu.com
location.hostname
  
// 端口号;比如8080
location.port

// url的路径部分,从 / 开始; 比如 https://www.baidu.com/s?ie=utf-8,那么 pathname = '/s'了
location.pathname

// 查询参数,从?开始;比如 https://www.baidu.com/s?ie=utf-8 那么 search = '?ie=utf-8'
location.search

// hash是页面中的一个片段,从 # 开始的,比如 https://www.baidu.com/#/a/b 那么返回值就是:"#/a/b"
location.hash 

hash 和 pushState 对比有如下缺点:

1. hash只能修改url的片段标识符的部分。并且必须从#号开始,但是pushState且能修改路径、查询参数和片段标识符。pushState比hash更符合前端路由的访问方式,更加优雅(因为不带#号)。

2. hash必须和原先的值不同,才能新增会话浏览历史的记录,但是pushState可以新增相同的url的记录

2. history模式

HTML5的History API为浏览器的全局history对象增加了该扩展方法。它是一个浏览器的一个接口,在window对象中提供了onpopstate事件来监听历史栈的改变,只要历史栈有信息发生改变的话,就会触发该事件。提供了如下事件:

window.addEventListener('popstate', function(e) {
  console.log(e)
});

history提供了两个操作历史栈的API: history.pushState 和 history.replaceState

history.pushState(data[,title][,url]); // 向历史记录中追加一条记录

history.replaceState(data[,title][,url]); // 替换当前页在历史记录中的信息。

如上html5中新增了上面这两个方法,该两个方法也可以改变url,页面也不会重新刷新。下面我们也可以来做个demo,来监听下popstate事件,现在在我js里面放入如下js代码:

window.addEventListener('popstate', function(e) {
  console.log(e)

hash模式的特点:

hash模式在浏览器地址栏中url有#号这样的,比如(http://localhost:3001/#/a). # 后面的内容不会传给服务端,也就是说不会重新刷新页面。并且路由切换的时候也不会重新加载页面。

history模式的特点:

浏览器地址没有#, 比如(http://localhost:3001/a); 它也一样不会刷新页面的。但是url地址会改变。

猜你喜欢

转载自www.cnblogs.com/wsk1576025821/p/10868676.html