2013-05-17 70 views
3

我想知道是否可以實施某種粗略的JavaScript防洪保護。 我的代碼通過AJAX接收來自服務器的事件,但有時這些事件可能相當頻繁(它們不受我控制)。JavaScript反氾濫垃圾郵件保護?

我試圖拿出打擊這種的方法,我已經寫了一個小腳本:http://jsfiddle.net/Ry5k9/

var puts = {}; 

function receiverFunction(id, text) { 
     if (!puts[id]) { 
      puts = {}; 
      puts[id] = {}; 
     } 

     puts[id].start = puts[id].start || new Date(); 
     var count = puts[id].count = puts[id].count + 1 || 0; 
     var time = (new Date() - puts[id].start) * 0.001; 

     $("text").set("text", (count/time.toFixed()).toString() + " lines/second"); 

     doSomethingWithTextIfNotSpam(text); 
    } 
}; 

我認爲可以證明對這些類型的攻擊有效,但我想知道它是否可以改進或可能改寫?到目前爲止,我認爲每秒超過3或2.5行的東西看起來像垃圾郵件,但隨着時間的推移(因爲開始標記被設置爲......以及......在開始時),犯罪者可以簡單地閒置一會兒然後開始洪水,實際上從來沒有通過每分鐘1行。另外,我想補充一點,我使用Mootools和Lo-Dash庫(也許它們提供了一些有趣的方法),但是如果可以使用本機JS來完成這項工作將會更好。

任何洞察力非常感謝!

+0

很可能,如果有人修建垃圾是他們沒有使用瀏覽器來做它的網站(即他們完全繞過JavaScript)。在任何情況下,如果有人將文本複製粘貼到輸入字段,您的方法可能會崩潰或認爲他們正在嘗試洪泛網站。 – JJJ

+0

@Juhana:但我從服務器接收事件(我無法控制)。 – VariousThings

+1

然後我真的不明白你要做什麼,對不起。如果事件來自服務器,那麼keydown事件試圖捕獲什麼? – JJJ

回答

1

我花了很多天思考有效措施來禁止消息氾濫,直到我遇到了在其他地方實施的解決方案。

首先,我們需要三樣東西,懲罰和得分變量,並在時間點爲最後一個動作發生:

var score = 0; 
var penalty = 200; // Penalty can be fine-tuned. 
var lastact = new Date(); 

接下來,我們通過以前的消息和電流之間的距離,時間減少評分。

/* The smaller the distance, more time has to pass in order 
* to negate the score penalty cause{d,s}. 
*/ 
score -= (new Date() - lastact) * 0.05; 

// Score shouldn't be less than zero. 
score = (score < 0) ? 0 : score; 

然後我們添加的消息點球並檢查它是否超過閾值:

if ((score += penalty) > 1000) { 
    // Do things. 
} 

不應該忘記更新之後最後一個動作:

lastact = new Date(); 
1

如果您擔心特定javascript函數觸發的頻率,您可以使用debounce的函數。

在你的榜樣,我想這會是這樣的:

onSuccess: function(){ _.debounce(someOtherFunction, timeOut)}; 

其中timeout是最大頻率想要someOtherFunction被調用。

+0

我使用的'onSuccess'函數非常複雜,並且取決於每個單獨函數的返回輸出(事件類型,例如「連接」,「斷開連接」等)。檢查源代碼,似乎將其刪除將返回「最後一次func調用的結果」,這可能會破壞已經很脆弱的代碼。 – VariousThings

+1

「已經脆弱的代碼」? - 聽起來像是重構時間... :) –

+0

@ma_il:哈哈,也許吧。我不得不重塑一切,「如果它有效,不要修復它」有點適用於此。 – VariousThings

1

我知道你問了關於原生JavaScript,但也許看看RxJS

JavaScript的RxJS或Reactive Extensions是用於轉換,組合和查詢數據流的 庫。我們的意思是所有 類型的數據,從簡單的值列表到事件系列 (不幸或其他),複雜的數據流。

有該網頁上,它使用throttle方法爲「忽略從其中隨後duetime參數之前的另一個值可觀察的序列值」(見source)的例子。

keyup = Rx.Observable.fromEvent(input, 'keyup').select(function(ev) { 
      return ev.target.value; 
     }).where(function(text) { 
      return text.length > 2; 
     }).throttle(500) 
     .distinctUntilChanged() 

可能有類似的方法來獲得您的2.5-3每秒,並忽略其餘的事件,直到下一秒。