2013-05-17 71 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每秒,并忽略其余的事件,直到下一秒。