web-dev-qa-db-ja.com

不明なIDでIntervalをクリアする方法は?

誰か(悪)がsetIntervalでタイマーを設定したが、そのIDがわからないとします(オブジェクトへの参照がなく、setIntervalが返されていることも、その値もありません)

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

それをクリアする方法はありますか?他の方法でタイマーにアクセスすることは可能ですか?または少なくとも特定のブラウザ/ JavaScriptエンジン?

デビッドフラナガンは、彼の大きなJSTDGと同様のトピックに触れています。インデックスのsetInterval() method, use in malicious codeキーが指す

...一部のブラウザは、繰り返されるダイアログボックスと長時間実行されるスクリプトを検出し、ユーザーにそれらを停止するオプションを提供します。ただし、悪意のあるコードはsetInterval()などのメソッドを使用してCPUをロードし、大量のメモリを割り当てることでシステムを攻撃する可能性があります。 Webブラウザがこの種の手に負えない攻撃を防ぐことができる一般的な方法はありません。実際には、この種のスクリプトの悪用に関与しているサイトに誰も戻ってこないため、これはWebでは一般的な問題ではありません。

24
mykhal

クイックテストから、すべての主要なブラウザ(最新の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>

これは停止しますall間隔、もちろんそのIDを知らずに特定の間隔を停止することはできません。

自分でテストできるので、上記のすべての主要なブラウザで動作するはずです。

Chromeでの経験的な試行では、setIntervalが呼び出しごとに増加する数値を返すことが示されています。したがって、setIntervalが最後のセットであることが確実な場合は、次のように機能します。

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

私はこれをお勧めするかどうかはわかりませんが;-)

13
HBP

#Shadow Wizardで提案されたアプローチを試しましたが、間隔をクリアするのに役立ちました。しかし、このアプローチには後で副作用がありました。私の特定のケースでは、後でjquery.fadeTo()を使用できませんでした。すべての間隔をクリアします。

私が決めたアプローチは、setIntervalメソッドを再定義し、再定義されたメソッドに間隔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] );
    }
}

これはうまくいくようです!

8
Mark Chackerian