深刻学习History对象管理浏览器会话历史

History对象容许咱们操做浏览器会话历史,即加载当前页面的标签页窗口或frame窗口的访问历史。以前有同窗咨询我如何实现拦截用户跳转页面并强制用户返回首页后从新请求页面,因而有了本篇博客的主题,本篇深刻介绍浏览器会话历史的操做,在最后对比加载页面的几种不一样方式,并提供一个实例給读者把玩。javascript

属性

  • History.lengthhtml

    只读的,其值为一个整数,标志包括当前页面在内的会话历史中的记录数量,好比咱们一般打开一个空白窗口,length为0,再访问一个页面,其length变为1。java

  • History.scrollRestorationweb

    容许web应用在会话历史导航时显式地设置默认滚动复原,其值为auto或manual。浏览器

  • History.state缓存

    只读,返回表明会话历史堆栈顶部记录的任意可序列化类型数据值,咱们能够以此来区别不一样会话历史纪录。安全

方法

  • History.back()函数

    返回会话历史记录中的上一个页面,等价于window.history.go(-1)和点击浏览器的后退按钮。工具

  • History.forward()学习

    进入会话历史记录中的下一个页面,等价于window.history.go(1)和点击浏览器的前进按钮。

  • History.go()

    加载会话历史记录中的某一个页面,经过该页面与当前页面在会话历史中的相对位置定位,如,-1表明当前页面的上一个记录,1表明当前页面的下一个页面。若不传参数或传入0,则会从新加载当前页面;若参数超出当前会话历史纪录数,则不进行操做。

  • History pushState()

    在会话历史堆栈顶部插入一条记录,参数包括,任意可序列化的object对象数据(可选),页面标题(可选),页面URL(非空)。

    目前,Firefox忽略页面标题参数。

  • History.replaceState()

    更新会话历史堆栈顶部记录信息,包括特定的任意可序列化的object对象数据(可选),页面标题(可选),页面URL。

值得注意的是,不管是replaceState()方法仍是pushState()方法,其更新或添加会话历史记录后,改变的只是浏览器关于当前页面的标题和URL的记录状况,并不会刷新或改变页面展现。

window.history

window的history是只读属性,该属性返回History对象的一个引用,支持咱们操做浏览器会话历史记录。

出于安全考虑,History对象不容许咱们经过JavaScript代码访问其余会话历史记录中其余页面的URL,可是它容许咱们在不一样页面间进行导航。

onpopstate事件

HTML5中,提供history.pushState()和history.replaceState()方法,支持咱们添加或更新会话历史记录,另外还提供window.onpopstate事件支持咱们对该操做进行监听。

pushState()

pushState()方法接收三个参数,一个state对象,一个页面标题,一个URL:

  1. 状态对象:

    1. 存储新添会话历史记录的状态信息对象,每次访问该条会话时,都会触发popstate事件,而且事件回调函数会接收一个参数,值为该事件对象的复制副本;
    2. 状态对象能够是任何可序列化的数据,浏览器将状态对象存储在用户的磁盘以便用户再次重启浏览器时能恢复数据;
    3. 一个状态对象序列化后的最大长度是640K,若是传递数据过大,则会抛出异常。
  2. 页面标题:

    1. 目前 ,该参数值会被忽略,暂不被使用,能够传入空字符串。
  3. 页面URL:

    1. 此参数声明新添会话记录的入口URL;
    2. 在调用pushState()方法后,浏览器不会加载URL指向的页面(在重启浏览器后或许会加载新页面 ),咱们能够在popstate事件回调中处理页面是否加载;
    3. 此URL必须与当前页面URL同源,,不然会抛异常;其值能够是绝对地址,也能够是相对地址,相对地址会被基于当前页面URL解析 获得绝对地址;若其值为空,则默认是当前页面URL。

pushState()方法能够改变URL地址栏,在会话历史堆栈顶部插入一条新会话记录,如:

var stateObj = { foo: "bar" };
    history.pushState(stateObj, "page 2", "bar.html");复制代码

假如当前访问页面blog.codingplayboy.com,则执行以上js代码后,浏览器地址栏变为http://blog.codin…

  • 若咱们点击浏览器的后退按钮,页面也不会变化,只是浏览器的地址栏URL变换为以前的blog.codingplayboy.com;
  • 若咱们点击跳转到blog.codingplayboy.com/about.html,…
  • 咱们能够在popstate事件回调中执行咱们的任务,可是必须知道的是,只有当当前页面DOM加载完成(即DOMContentLoaded事件发生)后才会触发popstate事件。
  • pushState()方法不会触发hashchange事件,即便URL的hash片断值改变。

replaceState()

与history.pushState()方法相比,history.replaceState()方法不建立新的会话历史,而是更新当前会话历史记录,如更新当前会话记录的状态对象或URL。

popstate事件

每次会话记录变换激活都会在window上触发popstate事件,若是激活的会话记录是经过replaceState()更新的或使用pushState()方法建立的,popstate事件对象的state属性值就是该会话记录状态对象的一个副本。

location.reload()与location.replace()小结

咱们知道location.reload()和location.replace()方法还有直接设置location值,均可以从新加载页面,可是这三种方式也是有区别的:

reload()

  • 语法

    location.reload(beForceGet)

  • 参数

    beForceGet,可选,值为truefalse;默认为false,表示是否从客户端缓存读取当前页;为true时,则从服务端从新请求页面(至关于F5刷新和history.go(0)方法)。复制代码

replace()

  • 语法

    location.replace(url)

  • 参数

    一个相对或绝对URL,使用相对于当前页URL解析后的URL替换当前会话记录的URL,效果与使用history.replaceState()方法修改URL相同;

  • 对比reload()

    location.reload()会取客户端的缓存页面,可是location.replace(url)老是从新请求加载url指向的页面。

location赋值

  • 语法

    location.href = url;

    location.assign(url);

  • 说明

    能够为location直接设置一个URL值,该值等效于使用pushState()修改URL,会建立一条新会话记录。

拦截用户返回页面及强制请求新页面实例

点此传送到实例访问地址

首先,咱们进入首页index.html,并点击任意跳转,跳转到第二页a.html(固然在实际应用中能够是任意页面),而后点击返回,咱们会发现,并无返回到咱们访问的首页,而是进入了咱们设置的拦截页,具体如何实现的呢,由于咱们在第二页中编写JavaScript代码实现:

;(function() {
        window.onpopstate = function(event) {
            console.log(event.state);
            location.replace('replace.html');
        };
        history.pushState({name: '惊鸿'}, '', 'a.html?history=1');
    })();复制代码

咱们调用pushState()方法建立了一条新会话记录(该会话URL为a.html?history=1,仔细看浏览器地址栏变URL变成了a.html?history=1,),并绑定了popstate事件回调,当浏览器返回时,会退回到上一条会话记录,即a.html会话,而后触发popstate事件,在事件回调函数中,咱们调用location.replace('replace.html')将a.html页面跳转至replace.html(能够是任意同源页面),这就实现了拦截用户跳转;随后,再次点击返回,会返回到咱们访问的第一个页面,咱们查看NetWork请求会发现不一样于以前返回的页面(请求状态码为304),其状态码是200,说明是一次新的请求,这是由于在replace.html页面中,加了以下代码:

;(function() {
        window.onpopstate= function(event) {
            console.log(event.state);
            document.location.replace(location.href);
        };
    })();复制代码

咱们在popstate事件回调中,使用location.replace()方法强制刷新了当前页面;当咱们在拦截页点击返回时,会回退到第一页会话,URL为index.html,而后触发popstate事件,执行document.location.replace(location.href);刷新页面。

pushState()和replaceState()能作的比咱们想象的要多,本文比较详细的对其进行了介绍,有兴趣的同窗能够参考MDN或玩w3c,进行更深刻的学习,也能够搜索PJAX,即PushState和Ajax,同时使用这两个工具,能够极大加快网站响应速度。

欢迎移步个人我的博客