一.hash
原理:
hash模式依靠的是 onhashchange() 事件去监听 location.hash 的改变。
特点:
- 出现在 URL 中,但是不会包括在 HTTP 请求中。
- 改变hash不会重新加载页面。
- 相同的 URL ,hash 不会触发添加到浏览器的历史记录栈
- 对后端无影响。
举例说明
// 例如当前地址的 URL 是:
// http://write.blog.csdn.net/postedit?id=1&name=2#123_234_567
// location 的 hash 对象,主要是设置或返回从 (#) 开始的 URL(锚),通过 location.hash来调用,是一个可读可写的字符串
location.hash="#123_234_567";
// location.search 是设置或返回从问号 (?) 开始的 URL(查询部分),也是一个可读可写的字符串
location.search="?id=1&name=2#123_234_567"
二.history
原理:
利用 H5 新增的两个 API pushState() 和 replaceState() 以及一个事件 popstate 来监听 URL 的变化
特点:
- URL 要与后端保持一致,如果要改为 history 模式需要后端配合,否则回报错
- 每次刷新都会向后端请求整个网址,也就是重新请求向服务器发送请求,如果后端无响应回弹出404
- 可以进行修改历史记录,并且不会立即向后端发送请求,只有点击刷新的时候才会发送请求
history api:
基本:
- history.go(n) 路由跳转几步,n为跳转页面步数,可以为负数
- history.back() 路由后退,相当于 history.go(-1),用户可点击浏览器左上角的后退按钮模拟此方法
- history.forward() 路由前进,相当于 history.go(1),用户可点击浏览器左上角的前进按钮模拟此方法
新增:
-
history.replaceState()切换地址栏中的 URL
然而这里有一个问题。
点击返回按钮后,我们会发现我们并没有返回到本文的 URL,而是返回到之前的任何页面。
这是因为replaceState不操纵浏览器的历史,它只是替换地址栏中的当前 URL。为了解决这个问题,我们需要使用以下pushState方法: -
history,pushState()在浏览器中添加历史记录,但是不会发生跳转,此方法接收三个参数
// state 一个与指定网址相关的状态对象,当popstate事件触发时,state会传入回调函数,可以通过event.state获取
// title 新页面标题,一般忽略。传null
// URL 设定新的历史记录 URl 必须与当前页面处在同一个域,浏览器的地址栏会显示此处的网址
// URL 可以是相对路径也可以是绝对路径
history.pushState(state, title, 'hello');
- popState 事件
每当同一个文档的浏览历史(即history)出现变化时,就会触发popState事件。
注意:
仅仅调用pushState方法或replaceState方法,并不会触发该事件,只有用户点击浏览器后退和前进按钮时,或者使用js调用back、forward、go方法时才会触发。另外该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件不会被触发使用的时候,可以为popState事件指定回调函数
页面第一次加载的时候,浏览器不会触发popState事件
addEventListener("popstate", function() {
// 监听浏览器前进后退事件,pushState 与 replaceState 方法不会触发
console.log(event.state)
})
举例说明
// 当前url是 https://www.baidu.com/a/
执行 history.pushState(null, null, './qq/')
则变成 https://www.baidu.com/a/qq/
执行 history.pushState(null, null, '/qq/')
则变成 https://www.baidu.com/qq/
history.replaceState(state, title, url)
// 与 pushState 基本相同,但她是修改当前历史记录,而 pushState 是创建新的历史记录
三.使用场景
一般情况下 vue-router 前端路由模式两种方式都可以,美观上history要更好一点,hash有自己特定的符号(#)。
hash:
只能改变 # 后面的内容,因此 URL # 前的路径只能一致
在 hash中 # 后面必须修改以后才能添加到新的记录栈中
hash 只能添加短字符串
history:
pushState() 设置新的 URL 可以是任何同源的 URL
pushState() 设置的 URL 与之前的一样也会被添加到历史记录栈中
pushState() 可以通过stateObject参数添加任意类型的数据到记录中
pushState() 可额外设置title属性供后续使用