ajax回退状态保持,实现异步请求ajax的前进和后退

我们知道 ajax 可以实现页面内容的无刷新更新,但页面更新之后如果想返回到之前的状态,传统的 ajax 是无法实现的。

例如,在一个查询页面上,为了改善用户体验,用户的查询使用了异步请求改变页面上的查询结果。经过若干次查询之后,用户尝试点击浏览器的回退按钮想回到上一次的查询结果,可想而知结果是回到了之前访问的站点,而不是该页面上一次的查询结果,类似这样的需求经常会遇到。难道鱼与熊掌真的不可兼得?HTML5 的出现让一切变得十分简单。

window.history

在此之前,我们先大概了解一下 window.history 对象,稍有前端开发经验的童鞋应该了解,可以忽略绕道。

window.history 是浏览器的历史访问对象,存放当前浏览器的访问历史栈。window.history 常用的接口有:

history.back(); // 后退

history.forward(); // 前进

history.go(n); // 前进或后退n步,例如history.go(-2)表示返回两步,history.go(1)相当于history.forward()

pushState

在 HTML5 出现之前,我们无法控制或操作一个浏览器上下文的会话记录,直至 HTML5 牛逼轰轰地引入了新的 API:history.pushState 和 history.replaceState,通过这个接口可以操作 window.history 对象的内容,并且做到无刷新改变页面 URL。

pushState 结合 ajax 使用,就可以实现异步请求的前进和回退。这就是传说中的 PJAX(pushState + ajax)。

PJAX 的原理是,在执行 ajax 请求时,将所需要存储的数据(可以是 title,url 或请求数据)存入一个 state 对象,调用 pushState 函数将 state 对象 push 入 window.history 栈中,pushState 函数的调用如下:

pushState(state, title, url)

pushState 接收一个 state 对象,该对象是一个可序列化的 json 对象(因此 DOM 节点不能作为 state 对象)。title 和 url 是该历史记录的标题和链接,调用 pushState 会将当前页面的标题和 url 无刷新地更新为指定的 title 和 url。

replaceState 和 pushState 的调用方式一致,不同在于 replaceState 会覆盖当前的历史记录,而不是 push 一条新的历史记录。

popstate event

PJAX 通常需要结合 window.onpopstate 来实现请求回退或前进。

window.onpopstate 会在浏览器回退或前进时触发,当事件被触发时,通过 event.state 可以获取保存在 history 栈中的 state 对象,从 state 对象中我们就可以获取先前我们通过 pushState 存入的数据,例如 title,url 或请求数据,根据这些数据,我们就可以重新发起请求,从而实现了请求的回退或前进。

简单来说,PJAX 就是利用 window.history 作为存储栈,采用 HTML5 提供的 pushState API,实现通过 url 来跟踪 ajax 的请求历史。

说到这里,有人可能会说,我用一个本地的数组来存储每次 ajax 请求的记录,不是一样也能实现所谓的 ajax 回退和前进?没错,使用一个本地数组或 localStorage 等方法也可以实现,但 PJAX 的优势在于它能无刷新修改当前页面的 URL,也就是说我们可以做到,直接访问修改后的 URL 也可以恢复某次 ajax 请求的状态,可用性更加好,并且这有利于搜索引擎索引我们的页面。

pjax example

上面说了那么多,归根到底 pjax 就只是做了一件事,用 url 来跟中 ajax 的请求历史。

那么应用到现实的需求开发中,使用 pjax 的关键点可以归纳为 2 个:

1) 执行 ajax 请求之后,将查询的必要参数拼接成 url 参数,生成新的 url,同时可以将一些额外的数据封装到 state 对象中,调用 pushState 将 url 压入 history。

window.history.pushState({key: value}, title, newUrl);

2) 绑定 popstate 事件,在回调中获取 state 对象,通过 location.href 可以获取当前 url,从 url 中解析请求参数,再次发起请求,从而实现请求的回退或前进。

// Bind popstate

window.addEventListener('popstate', function (e) {

if (history.state) {

var state = e.state;

var sUrl = location.href;

/*

issue ajax request

*/

}

}, false);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值