我想知道是否有可能实施某种粗略的JavaScript防洪保护。 我的代码通过AJAX从服务器接收事件,但有时这些事件可能非常频繁(它们不受我控制)。
我试图提出一种解决方法,我写了一个小脚本: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 :(得分:1)
如果您担心特定javascript函数触发的频率,您可以debounce
该函数。
在你的例子中,我猜它会是这样的:
onSuccess: function(){ _.debounce(someOtherFunction, timeOut)};
其中timeout
是您希望someOtherFunction
被调用的最高频率。
答案 1 :(得分: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,并忽略其余的事件,直到下一秒。
答案 2 :(得分: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();