如何使用 JavaScript 作弊打字测试来输入字母

Posted

技术标签:

【中文标题】如何使用 JavaScript 作弊打字测试来输入字母【英文标题】:How to cheat typing test using JavaScript to type the letters 【发布时间】:2021-05-19 05:16:32 【问题描述】:

我正在尝试提出一种解决方案,以虚拟按键进行打字测试。我想要的是获取文本并将单个字母存储在一个数组中,然后在每次按下之间有一些延迟按下所有键。

这是文本布局的 html。想象一下它有hello这个词。

<div class="digit-container">
    <div>
        <span>h</span>
    </div>
</div>
<div class="digit-container">
    <div>
        <span>e</span>
    </div>
</div>
<div class="digit-container">
    <div>
        <span>l</span>
    </div>
</div>
<div class="digit-container">
    <div>
        <span>l</span>
    </div>
</div>
<div class="digit-container">
    <div>
        <span>o</span>
    </div>
</div>

这是我想出的 javascript 代码。我已经设法将这些字母存储在一个数组中。

const elements = document.querySelectorAll(".digit-container > div > span");
const chars = Array.from(elements).map((item) => item.textContent);

const delay = 1000;

let i = 0;

const pressKey = () => 
  setTimeout(() => 
    const char = chars[i];

    const event = new KeyboardEvent("keyup", 
      key: char
    );

    document.body.dispatchEvent(event);

    if (i !== chars.length - 1) 
      i++;
      pressKey();
    
  , delay);
;

pressKey();

document.body.addEventListener("keyup", (e) => 
  console.log(e.key);
);

不过,这只会在控制台中显示 hello 字样。现在我希望 JavaScript 为这个字母数组发送按键 “h”、“e”、“l”、“l”、“o”。基本上,当我粘贴此代码并在控制台中按 Enter 时,我希望 JavaScript 在击键之间有几毫秒的延迟按“Hello”。这样我就可以完成打字测试了。如何让 JavaScript 进入按键?

【问题讨论】:

您究竟是在哪里尝试输入单词 hello? HTML 中没有表单元素来获取这些值。 我只想打字。它没有文本框。只需按hello 即可完成测试。 您需要为您要入侵的网站找到事件侦听器并连接到该网站 @freedomn-m 你能再解释一下吗? 如果我创建一个带有input 的页面并在该输入上监听keyup,那么您的代码会将keyup 发送到document - 我的事件处理程序不会触发。同样,如果我收听keydown 而您发送keyup,我将不会收到您的事件——无论输入/焦点如何——如果您发送错误的事件,我将不会收到。因此,您需要进一步破解您的网站以确定它如何处理输入。 【参考方案1】:

你被否决了很多,因为一般来说,人们不喜欢关于如何破解的问题......但我检查了是否可以回答你的问题,发现if the question focusses on the technical aspect and includes a reasonnable effort, it is okay。

我不得不承认我一直在寻找一个完整的理由来结束您的问题(!)...但是由于无论如何您都非常接近找到解决方案,这里是如何做到这一点以及如何防止它(对于网站所有者)。


因此,正如 cmets 中所提到的,您需要将事件分派到用户应该键入的正确元素...所以,而不是 document.body

但是关于调度哪些事件,这很简单。在输入输入时,触发的事件是(按顺序):keydownkeypressinputkeyup。见下文:

let targetInput = document.querySelector("#test");
let targetEvents = ["blur", "focus", "input", "keydown", "keyup", "keypress", "select"];

targetEvents.forEach(function (evt) 
  targetInput.addEventListener(evt, (event) => 
    console.log(`$event.type`)
    setTimeout(()=>console.clear(),1600)
  );
)
&lt;input type="txt" id="test"&gt;

因此,如果您想几乎完美地模拟用户键盘操作,我的建议是模拟这四个...而且您还必须将键值附加到输入值。

如何防止这种hack方法

也就是说……我也是非常不喜欢鼓励黑客攻击的人之一。因此,我还提供了一种方法来了解键盘操作是否是通过 JS 模拟的。 真正的键盘操作istrusted 属性设置为true。浏览器提供该信息,并且不能通过 JS 覆盖。因此,如果您是需要测试真实用户操作的网站的所有者,则需要检查事件的isTrusted 属性。

let targetInput = document.querySelector("#test");
let targetEvents = ["keydown", "keypress", "input", "keyup"];

targetEvents.forEach(function (evt) 
  targetInput.addEventListener(evt, (event) => 
    console.log(`$(event.isTrusted)?"Real user ":"JavaScript" - $event.type: $event.key`)
    if(event.isTrusted)
      setTimeout(()=>console.clear(),3000)
    
  );
)

let chars = ["H", "e", "l", "l", "o"];

let i = 0;
const pressKey = () => 
  setTimeout(() => 
    const char = chars[i];

    // Dispatch all the events
    targetEvents.forEach(function (evt) 
      let event = new KeyboardEvent(evt, 
        key: char,
        isTrusted: true  // Useless attempt overriding the isTrusted property
      );
      targetInput.dispatchEvent(event);
      
    );
    
    // Add the letter to the input value
    targetInput.value += char;

    if (i !== chars.length - 1) 
      i++;
      pressKey();
    
  , 150);
;

pressKey();
&lt;input type="txt" id="test"&gt;

【讨论】:

以上是关于如何使用 JavaScript 作弊打字测试来输入字母的主要内容,如果未能解决你的问题,请参考以下文章

markdown 打字稿...编码说明,提示,作弊,指南,代码片段和教程文章

如何根据输入为字符串或未定义来创建返回字符串或未定义的打字稿函数?

HTML 5 Gaming 是不是使用 Canvas 和 Javascript?在这种情况下如何防止作弊?

打字稿:仅测试 Nan、null 和 undefined

如何在 iphone 模拟器上使用键盘打字?

如何在 Javascript 中向 btn.innerHTML 添加函数?