2011-07-27 8 views
20

Powiedzmy, że ktoś (zło) wyznaczyła nam czasomierz z setInterval, ale nie znamy jego tożsamości (nie mamy odwołanie do obiektu, który setInterval wraca, ani jej wartość)Jak usunąć interwał z nieznanym identyfikatorem?

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

Czy istnieje sposób, aby to wyczyścić? Czy można uzyskać dostęp do timera w inny sposób? A przynajmniej w szczególności silnik przeglądarki/javascript?

David Flanagan dotyka podobnego tematu jego wielki JSTDG. setInterval() method, use in malicious code klucz w punktach indeksowych do

... Niektóre przeglądarki wykryć powtarzane okien dialogowych i skrypty długo działa i daje możliwość ich zatrzymać użytkownikowi . Ale złośliwy kod może używać metod takich jak setInterval() do ładowania procesora i może również atakować twój system przez przydzielanie dużej ilości pamięci. Nie ma żadnego ogólnego sposobu, w jaki przeglądarki internetowe mogą zapobiec tego typu atakom hamowanym. W praktyce nie jest to powszechny problem w sieci, ponieważ nikt nie wraca do witryny, która angażuje się w tego rodzaju nadużycia skryptów!

+2

Powiązane - http://stackoverflow.com/questions/3141064/how-to-stop-all-timeouts-and-intervals-using-javascript –

+0

Hmm .. inny pomysł - robi przez przypadek, że nadają funkcję Nazwa? –

+0

Shadow Wizard, w tym przypadku był niestety ustawiony w zamknięciu (co jest czasem uważane za fajną funkcję do celów bezpieczeństwa). Wiem, to pytanie jest nieco teoretyczne, ponieważ prawdopodobnie w większości przypadków możemy znaleźć i edytuj niepoprawny kod lokalnie w niektórych przeglądarkach – mykhal

Odpowiedz

36

Od szybkiego testu, wszystkimi popularnymi przeglądarkami (najnowszy Chrome, Firefox i IE) dają bardzo małych liczb jako identyfikator więc po prostu zapętlenie „ślepo” na wszystkich możliwych liczb powinna działać dobrze:

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

Pełny przykład:

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>

ten przestanie wszystkie interwały, nie może przestać konkretny przedział nie znając jego identyfikator kursu.

Jak sam możesz sprawdzić, powinien działać we wszystkich najważniejszych przeglądarkach wymienionych powyżej.

+3

Brutalna siła, dobra odpowiedź, ponieważ myślę, że PO otrzyma ! – Jamiec

+0

zobacz także mój komentarz poniżej Odpowiedź Hansa B PUFAL :) – mykhal

+0

Cóż, mój sposób zadziała, nawet jeśli w różnych punktach kodu jest wiele interwałów aktywowanych w różnych punktach kodu - jednak wyraźnie sposób Hansa jest bardziej elegancki i efektywny. –

10

Cóż, empirycznie Badania pokazują, że w Chrome setInterval zwraca liczbę, która przyrosty dla każdego połączenia. Więc jeśli jesteś pewien, że setInterval był ostatni ustawić następujące będzie działać:

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

Nie jestem pewien, polecam ten choć ;-)

+0

to jest możliwy sposób :) coś takiego jak 'pauseInterval' byłoby pomocne dla ręcznego znalezienia właściwego timera, ponieważ nie chcemy zabijać niewinnych .. – mykhal

4

Próbowałem podejście sugerowane przez #Shadow Wizard i pracował w wyczyszczenie odstępu. Jednak to podejście miało później skutki uboczne. W moim szczególnym przypadku nie mogłem użyć jquery.fadeTo() po wyczyszczeniu wszystkich interwałów.

Podejście, na które się zdecydowałem, jest czystszym rozwiązaniem, polegającym na ponownym zdefiniowaniu metody setInterval i zapisaniu identyfikatorów przedziałów w ponownie zdefiniowanych metodach. Jak pokazano tutaj, umieściłem identyfikatory w tablicy, a następnie wyczyściłem je wszystkie. Przy odrobinie udoskonalenia struktury do przechowywania macierzy można je oznaczyć i selektywnie usunąć.

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

To wydaje się działać!

+0

Niezły, to [rzeczywiście działa] (http://jsfiddle.net/vMRya/5/)! –

0

Rozwiązałem go za pomocą localstorage, zapisując tam identyfikator setInterval, i podnosząc go później, aby wyczyścić ten interwał.

Powiązane problemy