前端路由中的两种工作模式 -> hash与history

179 阅读4分钟

前言:

在SPA页面中,我们的路由主要是通过监听事件,利用js实现动态改变网页的内容,主要有两种实现方式:hash和history.

hash:

简述:

使用window.location.hash属性以及onhashchange事件,可以来实现监听浏览器地址的hash值的变化,然后执行相应的js来改变网页内容:

注意:

  • hash指的是url中#后面的字符,也叫做散列值。比如http://localhost/index.html#abc,这里的#abc就是hash;

  • hash值不会随着请求发送给服务端的,所以改变hash不会重新加载页面;

  • 监听window的hashchange事件,当hash值改变的时候,可以通过location.hash来获取和设置hash;

  • location.hash值的变化会直接反应到浏览器的地址栏;

特点:

1、#以及其后面的字符只是浏览器/客户端的状态,并不会通过http发送给服务器。

2、hash值的更改不会导致页面的刷新

3、hash的更改会在浏览器的访问历史中添加一条记录

4、hash值的更改会触发hashchange事件,我们可以添加监听事件

window.addEventListener("hashchange",callback,false)
触发hashchange事件的几种情况:

1、浏览器地址栏hash的变化(包括浏览器的前进、后退)会触发window.location.hash值的变化,从而触发onhashchange事件;

location.hash = '/#aaa'

2、当浏览器地址栏中URL包含哈希如 http://www.baidu.com/#home,这时按下输入,浏览器发送http://www.baidu.com/请求至服务器,请求完毕之后设置散列值为#home,进而触发onhashchange事件;

3、当只改变浏览器地址栏URL的hash部分,这时按下回车,浏览器不会发送任何请求至服务器,这时发生的只是设置hash值为新修改的哈希值,并触发onhashchange事件;

4、HTML标签的方式

<a href="#user">点击跳转到user</a>

histroy:

简述:

history是另一种模式(HTML5出现的),hash模式里面会带有*#,如果不想路径中带有#*,则可以使用history模式。这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。如图所示:

简述:

window.history 属性指向 History 对象,它表示当前窗口的浏览历史。当发生改变时,只会改变页面的路径,不会刷新页面。通过 history.length 可以得出当前窗口一共访问过几个网址。浏览器工具栏的“前进”和“后退”按钮,其实就是对 History 对象进行操作。

history对象的主要方法:
  • history.back(): 移动到上一个网址,等同于点击浏览器的后退键。

  • history.go(n):接受一个整数作为参数,移动到参数指定的网址。如果参数超过实际存在的网址范围,该方法无效果;如果不指定参数,默认参数为0,相当于刷新当前页面。

  • history.forward:移动到下一个网址,等同于点击浏览器的前进键。对于最后一个访问的网址,这个方法无效果。

特点:

1、路由跳转不需要重新加载页面。

2、看起来简单舒服一点,不带*#*。

3、兼容性没有hash好一点

原理:

利用HTML5中的history 中新增的pushState()、replaceState()方法来改变页面路径。

扩展:

HTML5中的几个API:

window.history.back();//后退
window.history.forward();//前进
window.history.go(-3);//接收一个Number参数,这里是后退三个页面
window.history.pushState(null,null,path);
window.history.replaceState(null,null,path);

popstate 事件

每当 history 对象出现变化时,就会触发 popstate 事件。

  • 仅仅调用pushState()方法或replaceState()方法 ,并不会触发该事件;

  • 只有当用户点击浏览器倒退按钮和前进按钮,或者使用 JavaScript 调用History.back()、History.forward()、History.go()方法时才会触发。

  • 页面第一次加载的时候,浏览器不会触发popstate事件。

使用时区别:

1、hash不需要服务器进行配置,也不会新发请求。history模式需要服务端做一些配置,且每访问一个页面都要发起请求,每个请求都需要务器进行路由匹配、查数据等等...做出响应。

2、hash不利于SEO(搜索引擎优化)。

3、history 的缺点就是当改变页面地址后,强制刷新浏览器时,(如果后端没有做准备的话)会报错,因为刷新是拿当前地址去请求服务器的,如果服务器中没有相应的响应,会出现 404 页面。