You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浏览器端JavaScript捕获键盘楔式条码/RFID设备输入并区分人工输入方案

网页端区分键盘楔外设与手动输入的实现方案

方案一:无驱动改造,纯前端事件监听实现(适配无权限改驱动的场景)

两类键盘楔模式外设和人手输入的核心差异是输入特征:人手打字单字符间隔通常大于80ms、间隔波动大,外设模拟输入的字符间隔稳定在10-30ms、整串输入耗时极短,配合可配置的前后缀可实现100%准确区分,具体实现逻辑如下:

  • 给条码扫描器配置专属起始/结束标记,比如起始字符设为不可见控制字符\u0002、结束字符保留默认回车再加专属后缀,避免和正常输入冲突。
  • 对无法配置前后缀的RFID读卡器,提前采样统计设备的固定特征:包括单字符输入平均间隔、输出编码的固定长度、编码字符集范围,作为后续判定的基准规则。
  • 全局绑定keydown事件做输入缓存,实时计算相邻字符的输入间隔:
    • 若相邻字符间隔超过80ms,直接清空缓存判定为手动输入,不做拦截
    • 捕获到回车符时判定为一串输入结束,统计整串的平均输入间隔、长度、前缀特征,分别匹配条码扫描器、RFID读卡器的规则,匹配成功则触发对应设备的自定义事件,同时阻止默认事件避免字符写入当前聚焦的输入框
    • 未匹配到任何外设规则的输入,按正常键盘输入放行
      核心逻辑参考代码:
const inputCache = [];
let lastKeyTime = 0;
// 阈值根据自己设备实际采样结果调整
const CONFIG = {
  maxManualInterval: 80,
  maxBarcodeInterval: 30,
  maxRfidInterval: 20,
  rfidFixedLength: 10,
  barcodePrefix: '\u0002'
};

document.addEventListener('keydown', (e) => {
  const currentTime = Date.now();
  const keyInterval = currentTime - lastKeyTime;
  lastKeyTime = currentTime;

  // 间隔超过手动输入阈值,清空缓存
  if (keyInterval > CONFIG.maxManualInterval && inputCache.length) {
    inputCache.length = 0;
    return;
  }

  // 回车触发输入结束判定
  if (e.key === 'Enter') {
    e.preventDefault();
    const inputStr = inputCache.map(i => i.key).join('');
    const avgInterval = (currentTime - inputCache[0].time) / inputCache.length;
    inputCache.length = 0;

    // 判定RFID输入
    if (inputStr.length === CONFIG.rfidFixedLength && avgInterval < CONFIG.maxRfidInterval) {
      window.dispatchEvent(new CustomEvent('rfid-read', { detail: inputStr }));
      return;
    }
    // 判定条码扫描输入
    if (inputStr.startsWith(CONFIG.barcodePrefix) && avgInterval < CONFIG.maxBarcodeInterval) {
      const barcodeVal = inputStr.replace(CONFIG.barcodePrefix, '');
      window.dispatchEvent(new CustomEvent('barcode-scan', { detail: barcodeVal }));
      return;
    }
    // 无匹配则放行正常回车逻辑
    return;
  }

  inputCache.push({ key: e.key, time: currentTime });
});

方案二:替换驱动转串口,调用Web Serial API通信(稳定性最高,适配内部受控场景)

不需要找第三方通用USB转串口驱动,直接用系统自带驱动即可实现,完全绕过键盘楔模式,从硬件层面区分设备、杜绝和手动输入混淆:

  • 打开Zadig工具,选中要改造的条码扫描器/RFID读卡器,记录设备的VID/PID,驱动选择列表里选系统自带的USB Serial Device(对应底层驱动为usbser.sys),替换原有HID键盘驱动。
  • 驱动替换完成后,设备会在系统设备管理器的「端口(COM和LPT)」分类下生成独立的虚拟COM口,此时设备不再触发键盘输入事件。
  • 前端代码中调用navigator.serialAPI,通过之前记录的VID/PID做端口过滤,用户授权后即可打开对应端口,按设备的通信波特率、数据位配置读取数据,两类设备对应不同的VID/PID,可直接区分输入来源,不需要做输入特征判定,稳定性远高于事件监听方案。

注意:驱动替换后原键盘楔模式会失效,仅适合设备完全由你方管控的内部业务场景;如果是面向外部用户的公网应用,无法要求用户替换驱动,优先选择方案一。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 18:31:01