Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как очистить интервал с неизвестным идентификатором?

Автор вопроса: mykhalОтветов: 4

Скажем, кто-то (зло) установил нам таймер с setInterval, но мы не знаем его ID (у нас нет ни ссылки на объект, который возвращает setInterval, ни его значения)

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

Есть ли способ, как его очистить? Можно ли получить доступ к таймеру каким-то другим способом? Или, по крайней мере, в конкретном браузере/движке javascript?

Дэвид Флэнаган затрагивает аналогичную тему в своем большом JSTDG. Ключ setInterval() method, use in malicious code в указателе указывает на

... Некоторые браузеры обнаруживают повторяющиеся диалоговые окна и длительные сценарии и дают пользователю возможность остановить их. Но вредоносный код может использовать такие методы, как setInterval(), для загрузки ЦП, а также может атаковать вашу систему, выделяя много памяти. Не существует общего способа, с помощью которого веб-браузеры могли бы предотвратить такого рода неуклюжие атаки. На практике это не является распространенной проблемой в Интернете, поскольку никто не возвращается на сайт, который занимается подобным злоупотреблением сценариями!

  • Связано - stackoverflow.com/questions/3141064/ Shadow Wizard Wearing Mask V2 27.07.2011
  • Хм.. еще одна идея - случайно они не дают функции имя? Shadow Wizard Wearing Mask V2 27.07.2011
  • Shadow Wizard, в данном случае, к сожалению, был установлен в закрытии (что иногда считается хорошей функцией для использования в целях безопасности).. я знаю, этот вопрос несколько теоретический, потому что мы, вероятно, можем в большинстве случаев найти и отредактировать неприятный код локально в некоторых браузерах mykhal 27.07.2011
  • Shadow Wizard... эээ, может быть, это не совсем закрытие. но это анонимная функция, которая была выполнена. наличие ссылки на функцию поможет нам как-то? mykhal 27.07.2011
  • да, вы можете (по крайней мере теоретически) переопределить функцию и поместить свою собственную функцию со своим собственным кодом. Функция, объявленная последней с тем же именем, будет выполняться во время выполнения. Shadow Wizard Wearing Mask V2 27.07.2011

javascripttimersetintervalclearinterval

Ответы

Ответ 1 · рейтинг 49 · Shadow Wizard Wearing Mask V2

Из быстрого теста все основные браузеры (последние версии Chrome, Firefox и IE) дают довольно маленькие числа в качестве идентификатора, поэтому просто "слепой" цикл по всем возможным числам должен работать нормально:

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, конечно.

Как вы можете проверить сами, он должен работать во всех основных браузерах, упомянутых выше.

Ответ 2 · рейтинг 13 · HBP

Что ж, эмпирические испытания в Chrome показывают, что setInterval возвращает число, которое увеличивается при каждом вызове. Поэтому, если вы УВЕРЕНЫ, что setInterval был последним установленным, будет работать следующее:

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

Я не уверен, что буду рекомендовать это, хотя ;-)

Ответ 3 · рейтинг 8 · Mark Chackerian

Я попробовал подход, предложенный #Shadow Wizard, и он сработал при очистке интервала. Однако впоследствии этот подход имел побочные эффекты. В моем конкретном случае я не смог использовать jquery.fadeTo() после очистки всех интервалов.

Подход, на котором я остановился, является более чистым решением, которое заключается в переопределении метода setInterval и сохранении идентификаторов интервалов в переопределенных методах. Как показано здесь, я помещаю идентификаторы в массив, а затем очищаю их все. Немного уточнив структуру хранения массивов, вы можете пометить их и выборочно очистить.

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] );
    }
}

Кажется, это работает!

Ответ 4 · Daniel Garcia Sanchez

Я решил это, используя localstorage, сохранив там идентификатор setInterval и забрав его позже, чтобы очистить этот интервал.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы