开发者社区> 史一试> 正文

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来。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
JS案例:Observer Pattern(观察者模式)和Publisher-Subscriber Pattern(发布者/订阅者模式)
JS案例:Observer Pattern(观察者模式)和Publisher-Subscriber Pattern(发布者/订阅者模式)
31 0
JavaScript设计模式-迭代者模式(18)
JavaScript设计模式-迭代者模式(18)
22 0
JavaScript设计模式-发布订阅模式(9)
JavaScript设计模式-发布订阅模式(9)
20 0
JavaScript设计模式-MVVM模式(7)
JavaScript设计模式-MVVM模式(7)
42 0
JavaScript设计模式-MVC模式(6)
JavaScript设计模式-MVC模式(6)
17 0
JS 中ES模式的export 和export default 的区别
JS 中ES模式的export 和export default 的区别
78 0
JavaScript 现代模式 "use strict"
JavaScript 现代模式 "use strict"
42 0
JavaScript 进阶第六章(this与函数的调用模式 )
JavaScript 进阶第六章(this与函数的调用模式 )
23 0
浅谈JS发布订阅模式
浅谈JS发布订阅模式
43 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Javascript异步编程
立即下载
Javascript中的对象
立即下载
JS零基础入门教程(上册)
立即下载