admin 管理员组

文章数量: 886992

这几行 javascript 代码能让你的浏览器崩溃?

上Demo,想先看效果的可以先戳一下链接:Crash当然自己不想点也可以把链接发给小伙伴 — http://lab.zeakhold/crash/

(温馨提示:访问前请保存电脑/手机正在编辑的任务,整人被打概不负责嘿嘿~)

事情还是得从一篇推文说起——2月17日, IT Security Tweets ™ 发了几行JavaScript代码,说是能让你的浏览器崩溃以及iPhone重启:

什么东西这么神奇??!

于是打开电脑跃跃欲试,当满怀好奇地在浏览器上执行了这段代码后发现: Chrome 立马陷入了卡死的状态,点击关闭窗口没响应!!

打开任务管理器,发现CPU已飙升至100%:

在任务管理器里结束 Chrome 进程,所幸一切恢复正常。

不过也纳闷着,这几行代码究竟又是什么梗??

var total = "";

for (var i = 0; i < 1000000; i++) {

total = total + i.toString();

history.pushState(0, 0, total);

}

从代码看应该是history对象的pushState()方法在1000000次的循环中耗尽了系统的资源。看了一下相关的博客介绍,才发现原来pushState()是HTML5引进的新特性之一,它的引进与Ajax有着密切的关系。

我们知道,Ajax的出现方便了用户浏览网页,它允许用户在不用刷新的情况下更新网站的内容,但是这样也引发了一个问题,就是更新网站内容之后,不同的页面之间还是有区别的,而这种区别无法体现在URL上:Ajax产生的页面变化并没有伴随着URL的改变,当前页的URL仍与前一页的URL一样,这就导致我们无法通过前进、后退来切换页面。在传统的浏览体验中,页面内容的改变往往会伴随着URL的改变,而这些改变对应着“前进”和“后退”,但是Ajax的出现破坏了这种独特的体验。为此,HTML5 给history对象新增了一些特性来解决这个问题,其中就包括上面代码里的pushState()方法。

根据W3C的HTML5文档,pushState()方法的作用是在浏览器的历史记录栈里面添加记录(Pushes the given data onto the session history),该方法包含三个参数:一个事件对象,一个加进历史记录的页面的标题(通常被浏览器忽略),一个加进历史记录的地址。这样一来,当Aja作做变更一次,就可以用pushState()方法添加一次历史记录,在此基础上再加上其它几个方法,便使得我们可以主动地对历史记录进行编辑,无刷新改变URL,从而弥补了使用Ajax带来的这个缺陷。

回到代码,for做了1000000次循环,浏览器的历史记录(压入URL)也就修改了1000000次,并且,每次循环的URL都在上一次的基础叠加,这样不断循环下去向history添加记录,迅速地消耗系统内存资源,从而导致浏览器的崩溃。

了解缘由后,选了几个手机设备做了测试,虽然没有出现twitter所说的能让iPhone设备重启的现象,但是都不约而同地搞挂了浏览器。

有了这段代码后,似乎又多了个整蛊小伙伴的新姿势嘿嘿~

本文标签: 代码 能让 几行 浏览器 大全