从 "thisisunsafe" 到 ComboKeys.js 组合键功能开发:一个隐藏指令引发的探索

🚀 突然记起的神秘的指令

在一个普通的工作日,我正测试一个新开发的 Web 应用,突然遇到了 Chrome 浏览器的 SSL 证书警告页面。

看着那个红色的"您的连接不是私密连接"警告,我像往常一样准备点击"高级"按钮,却发现没有"继续前往"按钮。

在这时,突然想起之前 twitter 上看到的一个小技巧:thisisunsafe 快速跳过指令。正巧在页面试了试,还真的有效!

🤔 好奇心在作祟

这个发现让我陷入了深深的思考:

  • 这是怎么实现的? Chrome 是如何监听键盘输入的?
  • 还有其他类似的隐藏指令吗? 比如badidea用于绕过恶意软件警告
  • 这种交互模式有什么特别之处? 为什么不用按钮而用键盘输入?

这可太好办了!开始考古!👀(准备抄作业了)

🔍 不辞辛苦翻找源码

chrome_thisisunsafe

通过查阅 Chromium 的源码,我发现了这个功能的实现原理,并构造了一个简化逻辑来复现:

// 简化版的实现逻辑
class SecurityInterstitial {
  constructor() {
    this.hiddenText = "";
    this.targetPhrases = ["thisisunsafe", "badidea"];
    document.addEventListener("keydown", this.handleKeyPress.bind(this));
  }

  handleKeyPress(event) {
    // 只监听字母键,忽略修饰键
    if (event.key.length === 1 && /[a-z]/i.test(event.key)) {
      this.hiddenText += event.key.toLowerCase();

      // 检查是否匹配目标短语
      for (const phrase of this.targetPhrases) {
        if (this.hiddenText.endsWith(phrase)) {
          this.bypassWarning();
          return;
        }
      }

      // 保持合理的缓冲区长度
      if (this.hiddenText.length > 20) {
        this.hiddenText = this.hiddenText.slice(-10);
      }
    }
  }
}

不错,这真是一个简单而巧妙的键盘序列检测系统。现在它是我的了!ctrl c ctrl v 启动!

💡 自己手搓一个实现吧

看到这个实现,我的 开发本能(摸鱼本能)被激发了:

"如果我能做一个更好玩又通用的前端组合键库、粘滞键库,岂不是很有趣?"

于是,ComboKeys 项目诞生了!

🛠️ 从想法到实现:ComboKeys 的发布

第一版:简单粗暴

最初的想法很简单,就是模仿 Chrome 的实现:

// 第一版的粗糙实现
class SimpleCombo {
  constructor(targetKeys, callback) {
    this.target = targetKeys.toLowerCase();
    this.buffer = "";
    this.callback = callback;

    document.addEventListener("keydown", (e) => {
      if (e.key.length === 1) {
        this.buffer += e.key.toLowerCase();
        if (this.buffer.endsWith(this.target)) {
          this.callback();
        }
      }
    });
  }
}

// 使用示例
new SimpleCombo("hello", () => alert("Hello World!"));

这个版本虽能正常工作,但局限性也很多:

  • 只能检测字母序列
  • 没有超时机制
  • 不支持组合键(Ctrl+C 这种)
  • 无法停止监听
  • 没有错误处理

第二版:功能升级

经过一番思考,我意识到需要继续开动脑筋 支持更复杂的场景 (填满我剩下的摸鱼时间):

比如,我们可以设计如下调用实现:

// 科乐美秘籍:↑↑↓↓←→←→BA
const konamiCode = new ComboKeys(["ArrowUp", "ArrowUp", "ArrowDown", "ArrowDown", "ArrowLeft", "ArrowRight", "ArrowLeft", "ArrowRight", "KeyB", "KeyA"]);

// Web应用快捷键:Ctrl+S保存
const saveShortcut = new ComboKeys(["ControlLeft", "KeyS"]);

// 隐藏功能激活:输入"admin"
const adminMode = new ComboKeys(["KeyA", "KeyD", "KeyM", "KeyI", "KeyN"]);

这就需要解决几个关键问题:

  1. 编码统一:键盘事件的event.code提供了标准的按键标识
  2. 模式区分:组合键(同时按住)vs 序列键(依次按下)
  3. 超时处理:序列键需要在合理时间内完成
  4. 状态管理:跟踪当前匹配进度

于是掐指一算,不如封装一个可以链式设定的类来实现,也方便后续修改扩充更多功能~ 😊

最终版:ComboKeys 2.0

经过多次迭代,最终形成了现在的 ComboKeys 2.0 构造:

// 更合理高效的API链式设置
const combo = new ComboKeys(["KeyH", "KeyE", "KeyL", "KeyL", "KeyO"])
  .timeout(2000) // 限定2秒内完成
  .onTrigger(() => console.log("Hello!")) // 触发回调
  .maxTriggers(3) // 限定最多触发3次
  .debug(true) // 允许开启调试输出
  .start(); // 开始监听

🎮 实战应用:迷宫逃脱游戏

为了测试 ComboKeys 的最终能力,我抽空也就顺便(其实因为还没摸到下班点儿呢)用AI再写了一个迷宫逃脱的demo游戏:

在线演示-迷宫逃脱游戏

迷宫逃脱游戏

基础操作

// 移动控制
new ComboKeys(["ArrowUp"]).onTrigger(() => movePlayer(0, -1));
new ComboKeys(["Space"]).onTrigger(() => attack());

隐藏指令

// 调试模式:显示钥匙位置
new ComboKeys(["KeyT", "KeyI", "KeyP", "KeyS"]).onTrigger(() => showKeyLocation());

// 简单模式:显示最佳路径
new ComboKeys(["KeyE", "KeyA", "KeyS", "KeyY"]).onTrigger(() => showBestPath());

更多隐藏指令,不如来看看源码怎么写的吧!😄

🧠 设计哲学:从 Chrome 快捷指令开始

在开发 ComboKeys 的过程中,我从 Chrome 的 thisisunsafe 实现中学到了很多:

1. 用户体验至上

  • 无感知输入:不需要焦点,不需要输入框,直接在页面上输入
  • 即时反馈:输入完成立即响应,无需额外确认
  • 容错设计:输入错误会自动重置,不会卡住

2. 安全性考虑

  • 故意隐藏:这些指令不会出现在界面上,避免误触
  • 有意设计thisisunsafe 这个短语明确表达了"我知道这不安全但我要继续"
  • 适度门槛:需要完整输入,有一定的使用门槛

3. 技术实现的合理改进

  • 事件驱动:基于标准的 DOM 事件
  • 状态管理:维护简单但有效的状态
  • 性能友好:轻量级实现,不影响页面性能

🚀 最终成果:不只是一次摸鱼

ComboKeys 最终不仅仅是一次摸鱼产生的组合键库,它代表了一种发现问题、追究问题、开发问题、收纳问题的思路。

功能特性

  • 🎯 直观易用:清晰的 API 设计,方法名语义明确
  • ⏱️ 超时控制:可设置按键间的最大时间间隔
  • 👂 精确监听:支持指定 DOM 元素监听范围
  • 🔄 链式调用:流畅的链式设定方式 API 设计
  • 🐛 调试友好:内置调试功能,详细的日志输出

应用场景

  • 游戏开发:复杂的按键组合和按键响应系统
  • Web 应用:快捷键和隐藏功能、事件处理
  • 创意交互:特殊的用户交互体验
  • 开发工具:调试和测试功能的快速触发

🎯 经验总结:从模仿到创新

摸鱼过程中一些体会:

1. 好的灵感来源于日常观察

一个简单的浏览器功能,背后可能隐藏着有趣的技术实现。保持好奇心,多问几个“为什么”和“如何实现”,可以常给自己布置支线任务“要不我也来写一个”。

2. 从模仿开始,但不止于造轮子

最初我只是想复现 Chrome 的快捷绕过功能,但在实现过程中迸发出更多的想法与可能性,最终创造出了一些有意思的小玩具。

话不多说放地址:

项目地址: ComboKeys on GitHub
在线演示: 迷宫逃脱游戏

P.S. 还记得那个年少时的无敌指令吗?在迷宫中试试 ↑↑↓↓←→←→BA,然后输入 AUTO 看看效果呗!兄弟萌记得来个Star啊⭐

posted @ 2025-09-16 17:28  evil7  阅读(16)  评论(0)    收藏  举报