START
- 番茄也写一写,前端路由的两种模式
- 时间仓促,能力有限,难免有言语不当之处,望指正。
后端路由
-
我最早接触路由这个概念呢,是在学习node.js 的时候。使用node.js 搭建一个后端服务,通过在后端服务配置不同的路由地址,浏览器请求这些地址。来获取各种内容(例如html,txt,json 等).
我眼中的路由呢,就好像是一种路径/地址,方便我们依据路径去寻找到对应的资源,仅此而已。
-
早期的一些网站,就是用的后端路由,每点击一个菜单,就会切换一个url 地址,来拿到不同的html 以及其他资源展示出来。 http://lazy_tomato/home => 获取并展示home页面
http://lazy_tomato/sayHello => 获取并展示sayHello页面
总结一下
后端路由:每次切换url ,会刷新页面,加载新的页面和资源。
前端路由
前端页面发展的历程
- 最初是后端把页面都处理好,直接返回给浏览器;
- 然后出现了ajax,页面上一部分交互是使用ajax去实时刷新的;
- 然后开始流行前端三大框架,然后开始流行单页面应用;
单页面应用(single page web application),简称SPA。
单页面应用,只有一个主页面,但是功能的切换,需要hash history 配合实现。
前端路由的工作方式
-
用户点击了页面上的路由链接; -
导致了url 地址栏中的值发生了变化,但是页面不会刷新(利用了hash history 实现); -
前端路由监听了地址的变化; -
前端路由把当前地址对应的组件渲染都浏览器中;
本质上,其实就是浏览器的url 变化,不刷新浏览器,切换页面展示。hash / history 就可以实现我们这一要求。
1.hash
hash 最明显的特点就是url 中有一个# 号。
例如:
https://www.baidu.com/#tomato
可以尝试一下啊,随便找个网址,在url 最后面添加# 和任意字符。发现在控制台的network 中并不会加载数据和页面。
怎么获取url 上的hash 值?可以通过location.hash 去获取
location.hash
怎么去监听hash 的变化呢?
window.addEventListener('hashchange', event => {
console.log(event)
})
测试截图如下:
2.history
除了hash 模式,还有一种模式: history 模式 ,它也可以改变url ,但不刷新页面。
我们可以在浏览器中 使用 window.history 打印一下它。又或者去MDN官网查看一下history 中包含那些属性和方法。
history.length
History.state
History.pushState()
History.replaceState()
History.back()
History.forward()
history.go(-1)
浏览器控制台上尝试一下这几个方法
表格可能看起来比较冗余,可以跳过这个表格,这个表格只是记录了一下我熟悉history 上的方法时,运行的结果。
浏览器的url | 控制台输入命令 | 输入命令后的url |
---|
https://www.baidu.com/ | history.pushState({},'','a1') | https://www.baidu.com/a1 | https://www.baidu.com/a1 | history.pushState({},'','a2') | https://www.baidu.com/a2 | https://www.baidu.com/a2 | history.pushState({},'','a3') | https://www.baidu.com/a3 | https://www.baidu.com/a3 | history.pushState({},'','a4') | https://www.baidu.com/a4 | https://www.baidu.com/a4 | history.back() | https://www.baidu.com/a3 | https://www.baidu.com/a3 | history.forward() | https://www.baidu.com/a4 | https://www.baidu.com/a4 | history.go(-2) | https://www.baidu.com/a2 | https://www.baidu.com/a2 | history.replaceState({},'','replacePage') | https://www.baidu.com/replacePage | https://www.baidu.com/replacePage | history.back() | https://www.baidu.com/a1 | https://www.baidu.com/a1 | history.forward() | https://www.baidu.com/replacePage | https://www.baidu.com/replacePage | history.forward() | https://www.baidu.com/a3 |
怎么去监听history 的变化呢?
window.onpopstate = function(){
console.log(arguments)
}
运行截图
总结:
可以自己去浏览器打印一下这几个方法,其实就一个容器,然后通过自带的方法,加减历史记录栈,此处加减规则为先进后出。
3.hash和history的相同点和不同点
相同点
- 都可以不刷新页面,切换
url 。
不同点
-
hash 模式有# ;history 没有; -
hash 只可修改 url 中# 后面的部分;history 设置新url 可以是与当前url 同源的任意url ; -
hash 模式下出现在url 中# 后面的部分,不会被包括在HTTP请求中,对后端没有影响,不会重新加载页面;history 模式下,前端的url 必须和实际向后端发起请求的url 一致,若刷新页面,后端路由未处理,将返回404错误。
如果是部署在nginx 上的话,可以进行如下处理
server {
listen 80;
server_name localhost;
location / {
root html/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
-
hash 只可添加短字符串;history 通过pushState() 第一个参数可以添加任意类型的数据到记录中;
vue-router 源码解读
后续补充
END
- 到这里基本上,路由两种模式都理解的很透彻了。
- 作者:番茄
- 编写时间:2022/04/28-20/24
|