HTML5 history API介绍

标签:JavaScript

上个月曾经看到一篇《Abusing the HTML5 History API for fun (and chaos)》,当时只是觉得很有趣,但由于忙工作而没去细看。今天把它从Google Reader里翻了出来,顺便把学到的知识记录在此。

首先要说的就是history是个全局变量,即window.history。看到这个变量名你一定很熟悉,因为经常可以看到用window.history.back()来返回上一页的JavaScript代码。
所以它并不是什么新东西,然而在HTML4的时代,我们只能使用它的这几个属性和方法:
  • length:历史堆栈中的记录数。
  • back():返回上一页。
  • forward():前进到下一页。
  • go([delta]):delta是个数字,如果不写或为0,则刷新本页;如果为正数,则前进到相应数目的页面;若为负数,则后退到相应数目的页面。
而HTML5为其又添加了这2个方法:
  • pushState(data, title [, url]):往历史堆栈的顶部添加一条记录。data为一个对象或null,它会在触发window的popstate事件(window.onpopstate)时,作为参数的state属性传递过去;title为页面的标题,但当前所有浏览器都忽略这个参数;url为页面的URL,不写则为当前页。
  • replaceState(data, title [, url]):更改当前页面的历史记录。参数同上。这种更改并不会去访问该URL。
不过根据《Dive Into HTML5》的介绍,目前只有Safari 5.0+、Chrome 8.0+、Firefox 4.0+和iOS 4.2.1+支持。如果想兼容老浏览器的话,可以试试History.js,而且它还修正了一些bug。

那么它有什么用呢?
我想你应该访问过GitHub吧。最近这个网站有个很明显的改进:点击代码文件夹和代码时,会用AJAX载入新内容,而外层的框架就不用重新下载了;重点是标题栏、地址栏和前进后退按钮也变化了,就像你实际打开了新的页面一样。
如果我没猜错的话,它应该是在加载完新页面后,用history.replaceState()更改了当前页的URL,并用history.pushState()添加了原页面的历史记录,最后再对document.title赋值来更改当前页的标题(以修正title参数被忽略的bug)。于是我查看了一下bundle_github.js,搜索history后就发现我的猜想应该是正确的。
而Google的20 Things I Learned About Browsers and the Web则将这种技术发挥得更赞了
当然,它还有其他一些好玩的用法,例如Eight Equals Equals Dee IN UR URLS

如果你像我一样为安全担忧的话,你肯定会注意到替换URL可能会是很危险的。
简单来说,我可以把一个链接指向网银,但实际上却用JavaScript捕捉click事件,定向到另一个页面;而在这个页面,我又把URL改成网银的URL,这样就伪造成网银的网站了。
不过实际上我的担心是多余的,replaceState()的URL参数必须和当前页的协议(如HTTP、HTTPS)和域名完全相同(使用不同的子域都不行),否则在Chrome上会报“Error: SECURITY_ERR: DOM Exception 18”之类的错误。(其他浏览器我就没测试了,应该都是差不多。)

其他内容我就偷懒不写了,这2篇文章已经写得很详细了:
Manipulating the browser history
Session history and navigation

0条评论 你不来一发么↓

    想说点什么呢?