1.hash模式
1)hash模式原理
hash模式的url会在尾巴后面带上#号,hash值的变化不会导致浏览器向服务器发出请求,不会导致重新加载页面,hash的改变的会触发onhashchange事件,可以监测浏览器的前进后退。hash的传参会有体积限制。
hash模式
背后的原理是onhashchange
事件,可以在window对象上监听这个事件:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue路由中hash模式的实现</title>
</head>
<body>
<button id="myBtn">改变hash的值</button>
<script>
//改变hash值的方法:
//1.在URL栏中主动的修改hash值
//2.根据浏览器的前进,后退按钮改变hash值
//3.通过addEventListener,js的方法改变hash值
//hash值改变,页面不刷新。
const myBtn = document.getElementById('myBtn');
//浏览器提供了一个方法,用来监听hash的改变
window.onhashchange = (e) => {
console.log('老的url',e.oldURL)
console.log('新的url',e.newURL)
//location下面有个hash属性可以获取hash值
console.log('location',location)
console.log('hash',location.hash)
}
//DOM加载完毕的时候,就加载location.hash
window.addEventListener('DOMContentLoaded',()=>{
console.log(location.hash);
})
//给按钮绑定一个点击事件,当它被点击的时候,执行一个回调
myBtn.addEventListener('click', ()=>{
//注意location的href方法和location的hash方法的区别
location.href = '#/user'
})
</script>
</body>
</html>
2)hash路由 优缺点
(1)优点
- 实现简单,兼容性好
- 绝大数前端框架均提供了给予hash路由实现
- 不需要服务器端进行任何设置和开发
- 处了加载资源和ajax请求以外,不会发起其它的请求
(2)缺点
- 对于部分需要重定向的操作,后端无法获取hash部分内容,导致后台无法取得url中的数据,典型的例子就是微信公众号的oauth验证
- 服务器端无法准确跟踪前端路由信息
- 对于需要锚点功能的需求会与目前路由机制冲突
2.history模式
1)history模式的原理
history模式不仅可以在url里面放参数,还可以将数据存放在一个特定的对象中需要与后端配合,后端可以拿到路由信息。
history.pushState(), history.replaceState()
history.go(), history.back(), history.forward()
2)history(browser)路由 优缺点
(1)优点
- 对于重定向过程中不会丢失url的参数。后端可以拿到这部分数据。
- 绝大数前端框架browser的路由实现
- 后端可以准确跟踪路由信息
- 可以使用history.state来获取当前url对应的状态信息
(2)缺点
- 兼容性不如hash路由(只兼容到IE10)
- 需要后端支持,每次返回html文档
3.hash模式和history模式的区别
- 从原理角度来说:hash模式背后的原理是onhashchange()事件,而histoy模式则是利用History对象中的pushState()方法和repalceState()方法(其中这两个对象是HTML5新增的方法)。这个两个方法应用于浏览器的历史记录栈,在当前已有的back(),forward(),go()方法的基础之上,这两个方法提供了对历史记录进行修改的功能。当这两个方法执行修改的时候,只能改变当前地址栏的URL,但浏览器不会向后端发送请求,也不会触发popstate事件的执行。
- 从兼容性的角度来说:hash路由的兼容性比history路由要好
- 从形式上来看:hash模式url里面永远带着#号,而history模式不带#,history模式更加的美观。
- 从使用的角度来看:history模式有一个问题,那就是在访问二级页面的时候,做刷新操作,会出现404错误,那么就需要和后端人配合,让他配置一下apache或者是nginx的url重定向,重定向到你的页面路由上就可以。
4.hash模式和history模式的相同点
hash模式和history模式都属于浏览器自身的特性,Vue-Router和React-Router都只是利用浏览的这两个特性(通过调用浏览器的接口)来实现前端路由。