检测页面上的自动点击

11

我正在尝试开发一个库,用于检测页面上的自动点击。该库将被导入到多个不同的页面中,其中一些页面会有jquery,其他页面则没有,或者会有其他不同的库,因此我的解决方案应该是纯javascript。

目标是拥有几个安全层,并且第一层将位于javascript中,这个库不会是防止自动点击的唯一措施,但应提供尽可能多的信息。

想法是截取在页面上发生的所有点击和触摸事件,并且如果这些事件是由脚本生成的,那么就会发生一些事情(应该是一个ajax调用,或者在表单中设置一个值,或者设置cookie或其他某些东西,在这个阶段这并不重要)。

我已经编写了一个非常简单的脚本,用于检查计算机生成的点击:

(function(){
    document.onreadystatechange = function () {
      if (document.readyState === "interactive") {
        try{
            document.querySelector('body').addEventListener('click', function(evt) {    

                console.log("which", evt.which);
                console.log("isTrusted", evt.isTrusted);    
            }, true); // Use Capturing              
        }catch(e){
            console.log("error on addeventlistener",e);
        }
      }
    }   
}());

我曾在一个没有其他js代码的HTML页面上看到这个工作,但是自从我添加了这个JavaScript来测试自动点击检测之后,简单地说"什么都没发生",而且连自动点击和检测都没有发生。

如果在控制台中使用下面的相同代码,则可以正常工作,并且截获并评估事件。以下是使用的脚本:

document.onreadystatechange = function () {
        if (document.readyState === "interactive") {
 //1 try
            el = document.getElementById('target');
            if (el.onclick) {
               el.onclick();
            } else if (el.click) {
               el.click();
            }
            console.log("clicked")
        }
 //2 try
        var d = document.createElement('div'); d.style.position = 'absolute'; d.style.top = '0'; d.style.left = '0'; d.style.width = '200px'; d.style.height = '200px'; d.style.backgroundColor = '#fff'; d.style.border = '1px solid black'; d.onclick = function() {console.log('hello');}; document.body.appendChild(d);
    }

这个HTML页面非常简单:

<body>
    <h1>Hello, world!</h1>
    <div id="target"> aaaaa </div>
</body>

为了测试目的,我在头部添加了检测库,而“autoclick”代码就在</body>标签后面。

我猜问题在于“如何附加事件处理程序”,或者“何时附加”,所以我想问的是有什么方法可以“确定地”拦截点击事件,想法是拦截每个元素的点击事件,包括当前和未来的元素,我并不想要阻止它们,只是想要确保以某种方式拦截它们。当然,我不能拦截那些已被阻止且不冒泡的事件,但我希望尝试将我的js放在其他任何js之前。

你有关于这个的一些想法吗?

示例的jsfiddle


请不要在问题标题中添加标签。 - Liam
添加了一个带有代码的 JS Fiddle。 - Matteo Bononi 'peorthyr'
2
应该使用哪个库? - Matteo Bononi 'peorthyr'
我相信你知道可以在操作系统层面上自动化外部点击吗?我不确定这是否是你想要停止的事情,但如果是,那么这将是另一个完全不同的问题,因为没有办法基于JS事件对象检测它。 - David A
是的,主要想法是有几层安全保障,这只是最高的一层,当然还必须实施许多其他检查,如用户行为、IP过滤等等。 - Matteo Bononi 'peorthyr'
显示剩余2条评论
3个回答

8

当没有其他第三方库时,使用document.onreadystatechange仅在简单情况下按预期工作。将您的代码包装在本机DOMContentLoaded事件中。

document.addEventListener("DOMContentLoaded",function(){
  document.body.addEventListener('click', function(evt) {
    if (evt.target.classList.contains('some-class')) {} // not used
    console.log("which", evt.which);
    console.log("isTrusted", evt.isTrusted);
  }, true);

  //this is the autoclick code!
  el = document.getElementById('target');
  if (el.onclick) {
    el.onclick();
  } else if (el.click) {
    el.click();
  }
  console.log("clicked")
});
<html>

  <head>
    <title>Hello, world!</title>
  </head>

  <body>
    <h1>Hello, world!</h1>
    <div id="target"> aaaaa </div>
  </body>

</html>


谢谢,这正是我一直在寻找的内容,主要问题在于“确保我的代码能够运行,无论周围的环境如何”。 - Matteo Bononi 'peorthyr'

6

如果您查看传递给点击或其他事件函数的事件参数,您可以查找以下内容,这是一个明显的迹象,表明点击者不是人类...

event.originalEvent === undefined

从您所说的内容,我会使用以下方法来跟踪点击...
$(document).on("click", function(event){
    if(event.originalEvent.isTrusted){
       //not human
    }else{
       //human
    }
});

这可能是一个好主意,我一定会把它加入到逻辑中。 - Matteo Bononi 'peorthyr'

1

您能检查是否在100毫秒内同时发生了click事件和mouseuptouchend事件吗?如果没有,那么很可能是自动化事件。

let mouseuportouchend = false;
let click = false;
let timer = null;

const regMouseupOrTouchend = function(){
    mouseuportouchend = true;
    if (!timer) timer = setTimer();
}

const regClick = function(){
    click = true;
    if (!timer) timer = setTimer();
}

const setTimer = function(){
    timer = setTimeout(()=>{
        if (click && mouseuportouchend) console.log("Manual");
        else console.log ("Auto");
        click=false;
        mouseuportouchend=false;
        timer=null;
    }, 100)
}
let el = document.getElementById('target');
el.addEventListener("click",regClick);
el.addEventListener("mouseup", regMouseupOrTouchend);
el.addEventListener("touchend", regMouseupOrTouchend);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接