JS之hash和history两种模式

简介: JS之hash和history两种模式

众所周知,vue-router有两种模式,hash模式和history模式,这里来谈谈两者的区别。


hash模式


hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件:


window.onhashchange = function(event){
   console.log(event.oldURL, event.newURL);
   let hash = location.hash.slice(1); 
   document.body.style.color = hash;
}


通过改变hash来改变页面字体颜色,一定程度上说明了原理。hash发生变化的url都会被浏览器记录下来,从而浏览器的前进后退都可以用了,点击后退或者前进时,页面字体颜色也会发生变化。这样一来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来。


history模式


HTML5引入了 history.pushState() 和 history.replaceState() 方法,它们分别可以添加和修改历史记录条目。这些方法通常与window.onpopstate 配合使用。


pushState 方法


使用 history.pushState() 可以改变referrer,它在用户发送 XMLHttpRequest 请求时在HTTP头部使用,改变state后创建的 XMLHttpRequest 对象的referrer都会被改变。因为referrer是标识创建 XMLHttpRequest 对象时 this 所代表的window对象中document的URL。


假设在 http://mozilla.org/foo.html 页面的console中执行了以下 JavaScript 代码:


window.onpopstate = function(e) {
   alert(2);
}
let stateObj = {
    foo: "bar",
};
history.pushState(stateObj, "page 2", "bar.html");


这将使浏览器地址栏显示为 http://mozilla.org/bar.html,但并不会导致浏览器加载 bar.html ,甚至不会检查bar.html 是否存在。


假如现在用户在bar.html点击了返回按钮,将会执行alert(2)。


onpopstate


window.onpopstate是popstate事件在window对象上的事件处理程序.


调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法),此外,a 标签的锚点也会触发该事件.


假如当前网页地址为http://example.com/example.html,则运行下述代码后:


window.onpopstate = function(event) {
  alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
//添加并激活一个历史记录条目 http://example.com/example.html?page=1,条目索引为1
history.pushState({page: 1}, "title 1", "?page=1");  
//添加并激活一个历史记录条目 http://example.com/example.html?page=2,条目索引为2  
history.pushState({page: 2}, "title 2", "?page=2");  
//修改当前激活的历史记录条目 http://ex..?page=2 变为 http://ex..?page=3,条目索引为3 
history.replaceState({page: 3}, "title 3", "?page=3"); 
history.back(); // 弹出 "location: http://example.com/example.html?page=1, state: {"page":1}"
history.back(); // 弹出 "location: http://example.com/example.html, state: null
history.go(2);  // 弹出 "location: http://example.com/example.html?page=3, state: {"page":3}


通过pushstate把页面的状态保存在state对象中,当页面的url再变回这个url时,可以通过event.state取到这个state对象,从而可以对页面状态进行还原,这里的页面状态就是页面字体颜色,其实滚动条的位置,阅读进度,组件的开关的这些页面状态都可以存储到state的里面。


history模式的问题


通过history api,丢掉了丑陋的#,但是它也有个问题:不怕前进,不怕后退,就怕刷新,(如果后端没有准备的话),因为刷新是实实在在地去请求服务器的,不玩虚的。 在hash模式下,前端路由修改的是#中的信息,而浏览器请求时是不带它玩的,所以没有问题.但是在history下,你可以自由的修改path,当刷新时,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。

目录
相关文章
|
7月前
|
设计模式 缓存 JavaScript
JavaScript 简单实现观察者模式和发布-订阅模式
JavaScript 简单实现观察者模式和发布-订阅模式
32 0
|
8月前
|
JavaScript
js节点、属性操作,计时器,location、history对象,常见键盘事件
js节点、属性操作,计时器,location、history对象,常见键盘事件
|
10天前
|
JavaScript 前端开发 IDE
【JavaScript与TypeScript技术专栏】JavaScript与TypeScript混合编程模式探讨
【4月更文挑战第30天】本文探讨了在前端开发中JavaScript与TypeScript的混合编程模式。TypeScript作为JavaScript的超集,提供静态类型检查等增强功能,但完全切换往往不现实。混合模式允许逐步迁移,保持项目稳定性,同时利用TypeScript的优点。通过文件扩展名约定、类型声明文件和逐步迁移策略,团队可以有效结合两者。团队协作与沟通在此模式下至关重要,确保代码质量与项目维护性。
|
19天前
|
JavaScript 前端开发 索引
JavaScript中的正则表达式:使用与模式匹配
【4月更文挑战第22天】本文介绍了JavaScript中的正则表达式及其模式匹配,包括字面量和构造函数定义方式,以及`test()`、`match()`、`search()`和`replace()`等匹配方法。正则表达式由元字符(如`.`、`*`、`[]`)和标志(如`g`、`i`)组成,用于定义搜索模式。文中还分享了正则使用的技巧,如模式分解、非捕获分组和注释。掌握正则表达式能提升文本处理的效率和代码质量。
|
1月前
|
JavaScript
【归总】原生js操作浏览器hash、url参数参数获取/修改方法合集
【归总】原生js操作浏览器hash、url参数参数获取/修改方法合集
|
5月前
|
前端开发 JavaScript
JavaScript基础知识:JavaScript 中的异步编程有哪些模式?
JavaScript基础知识:JavaScript 中的异步编程有哪些模式?
40 0
|
10月前
|
设计模式 前端开发 JavaScript
|
10月前
|
设计模式 前端开发 JavaScript
|
6月前
|
JavaScript 程序员 Go
一图看懂编程语言迁移模式:终点站是Python、Go、JS
一图看懂编程语言迁移模式:终点站是Python、Go、JS
|
6月前
|
存储 前端开发 JavaScript
如何使用CSS和JavaScript实施暗模式?
如何使用CSS和JavaScript实施暗模式?