如何清除ID未知的Interval?

IT技术 javascript timer setinterval clearinterval
2021-03-02 07:27:13

假设有人(邪恶)为我们设置了一个计时器setInterval,但我们不知道它的 ID(我们没有对对象的引用,setInterval 正在返回,也没有它的值)

(function(){
  setInterval(function(){console.log('pwned')},
              10000)
})();

有没有办法,如何清除它?是否可以通过其他方式访问计时器?或者至少特别是浏览器/javascript引擎?

大卫·弗拉纳根 (David Flanagan) 在他的大 JSTDG 中也谈到了类似的话题。 setInterval() method, use in malicious code索引中的键指向

... 一些浏览器检测重复的对话框和长时间运行的脚本,并为用户提供停止它们的选项。但是恶意代码可以使用诸如 setInterval() 之类的方法来加载 CPU,还可以通过分配大量内存来攻击您的系统。Web 浏览器没有通用的方法可以防止这种笨手笨脚的攻击。实际上,这不是 Web 上的常见问题,因为没有人会返回从事此类脚本滥用的站点!

4个回答

从快速测试来看,所有主要浏览器(最新的 Chrome、Firefox 和 IE)都提供了非常小的数字作为 ID,因此只需“盲目地”遍历所有可能的数字就可以正常工作:

function ClearAllIntervals() {
    for (var i = 1; i < 99999; i++)
        window.clearInterval(i);
}

完整示例:

window.onload = function() {
    window.setInterval(function() {
        document.getElementById("Tick").innerHTML += "tick<br />";
    }, 1000);
    window.setInterval(function() {
        document.getElementById("Tack").innerHTML += "tack<br />";
    }, 1000);
};

function ClearAllIntervals() {
    for (var i = 1; i < 99999; i++)
        window.clearInterval(i);
}
#Placeholder div { width: 80px; float: left; }
<button type="button" onclick="ClearAllIntervals();">Clear All</button>
<div id="Placeholder">
    <div id="Tick"></div>
    <div id="Tack"></div>
</div>

这将停止所有间隔,当然不能在不知道其 ID 的情况下停止特定间隔。

由于您可以自己测试,它应该适用于上述所有主要浏览器。

好吧,即使在代码的不同点激活了很多间隔,我的方法也能奏效——但显然 Hans 方法更优雅、更高效。
2021-04-28 07:27:13
也可以在 Hans B PUFAL 的回答下面看到我的评论:)
2021-05-11 07:27:13
聚会有点晚了 - 应该注意的是,setIntervalsetTimeout使用相同的 ID 池,因此这也会取消任何setTimeouts。
2021-05-16 07:27:13

好吧,Chrome 中的经验试验表明,它setInterval返回一个数字,每次调用都会增加。因此,如果您确定 setInterval 是最后一组,则以下内容将起作用:

function clearLastInterval () {
  var i = setInterval (function () {}, 10000);
  clearInterval (i-1);
  clearInterval (i);
}

我不确定我会推荐这个 ;-)

这是一种可能的方式:) 类似的东西pauseInterval将有助于手动查找正确的计时器,因为我们不想杀死无辜的人..
2021-04-25 07:27:13

我尝试了#Shadow Wizard 建议的方法,它可以清除间隔。然而,这种方法后来产生了副作用。在我的特殊情况下,清除所有间隔后我无法使用 jquery.fadeTo() 。

我选择的方法是一种更简洁的解决方案,即重新定义 setInterval 方法并将间隔 id 保存在重新定义的方法中。如此处所示,我将 id 放入一个数组中,然后清除所有这些 id。通过对存储数组的结构进行更多改进,您可以标记它们并有选择地清除它们。

var intervalTracking = new Array();
var intervalCount=0;

window.oldSetInterval = window.setInterval;
window.setInterval = ( function(func, interval) {
    var interval = oldSetInterval(func, interval);
    intervalTracking[++intervalCount]=interval;
    return interval;
});

function clearAllIntervals() {
    for (var i = 0 ; i <= intervalCount ; i++) {
    window.clearInterval( intervalTracking[i] );
    }
}

这似乎有效!

我通过使用 localstorage 解决了这个问题,在那里保存了 setInterval 的 id,稍后再拿起它以清除该间隔..