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

如何在JS/TS网页应用中本地直连POS热敏打印机(无需服务器)

解决方案:浏览器直接连接局域网EPSON TM-T20III热敏打印机

为什么WebSocket方案失效

EPSON TM-T20III的9100端口是原始TCP字节流端口,仅接收纯打印指令数据,不支持WebSocket协议。WebSocket连接时的HTTP握手请求头会被打印机当成普通文本直接输出,这是因为它无法识别WebSocket的协议规则,只会把收到的所有字节内容打印出来。

浏览器安全限制下的可行方案

浏览器出于安全策略禁止直接发起TCP连接,因此Node.js net模块只能在本地Node环境或服务器端使用。以下是无需额外服务器的前端原生/官方方案:

方案1:EPSON官方ePOS-Print JavaScript SDK(推荐)

EPSON专门提供了网页端控制打印机的SDK,封装了底层网络通信逻辑,可直接在浏览器中通过局域网连接打印机,无需额外服务器。

示例代码:

// 先引入SDK文件(从EPSON官网下载后本地引入)
// <script src="./epos-print-5.0.0.js"></script>

async function printToEpsonPrinter() {
  // 初始化打印机连接(TCP://打印机IP)
  const printer = new epos.Printer('TCP:192.168.1.171', {
    timeout: 3000,
    bufferSize: 1024
  });

  try {
    // 建立连接
    await new Promise((resolve, reject) => {
      printer.connect(err => err ? reject(err) : resolve(null));
    });

    // 添加打印内容与指令
    printer.addText('测试打印内容\n\n');
    printer.addCut(); // 切纸指令

    // 执行打印
    await new Promise((resolve, reject) => {
      printer.send(err => err ? reject(err) : resolve(null));
    });

    console.log('打印成功');
  } catch (error) {
    console.error('打印失败:', error);
  } finally {
    // 断开连接
    printer.disconnect();
  }
}

// 绑定按钮触发打印
document.getElementById('print-btn')?.addEventListener('click', printToEpsonPrinter);

注意事项:

  • 需从EPSON官网下载SDK文件,本地引入至项目
  • 支持绝大多数EPSON热敏打印机,兼容性最优
  • 需在HTTPS环境下运行(localhost开发环境不受限制)

方案2:浏览器Serial API(原生方案)

现代Chrome/Edge浏览器支持Serial API,可直接访问本地串口/USB转串口设备。若打印机通过USB或串口连接客户端设备,此方案无需依赖第三方SDK。

示例代码:

async function connectPrinterViaSerial() {
  try {
    // 请求用户选择串口设备
    const port = await navigator.serial.requestPort();
    // 打开串口(TM-T20III默认波特率9600)
    await port.open({ baudRate: 9600 });

    // 构造打印数据(含ESC/POS指令)
    const encoder = new TextEncoder();
    const printText = encoder.encode('测试打印内容\n\n');
    const cutCommand = new Uint8Array([0x1B, 0x69]); // ESC/POS切纸指令
    const fullData = new Uint8Array([...printText, ...cutCommand]);

    // 发送数据
    const writer = port.writable?.getWriter();
    if (writer) {
      await writer.write(fullData);
      writer.releaseLock();
      console.log('打印完成');
      await port.close();
    }
  } catch (error) {
    console.error('打印出错:', error);
  }
}

// 触发打印
document.getElementById('print-btn')?.addEventListener('click', connectPrinterViaSerial);

注意事项:

  • 仅支持Chrome 89+/Edge 89+及以上版本
  • 打印机需通过USB或串口转USB适配器连接客户端
  • 需HTTPS环境(localhost除外)

方案3:WebUSB API(USB连接专属)

若打印机通过USB直连客户端,可使用WebUSB API访问设备。需注意打印机需支持USB CDC类规范(TM-T20III USB模式支持)。

示例代码:

async function connectViaWebUSB() {
  try {
    // 请求USB设备(匹配EPSON TM-T20III的VID/PID)
    const device = await navigator.usb.requestDevice({
      filters: [{ vendorId: 0x04B8, productId: 0x0E15 }]
    });

    await device.open();
    await device.selectConfiguration(1);
    await device.claimInterface(0);

    // 发送打印数据与切纸指令
    const encoder = new TextEncoder();
    const printData = encoder.encode('测试打印\n\n');
    const cutCmd = new Uint8Array([0x1B, 0x69]);
    await device.transferOut(1, new Uint8Array([...printData, ...cutCmd]));

    console.log('打印完成');
    await device.close();
  } catch (error) {
    console.error('错误:', error);
  }
}

总结

  • 放弃WebSocket方案,打印机不支持该协议
  • 优先选择EPSON官方SDK,兼容性与易用性最佳
  • 原生方案优先考虑Serial API,适配USB/串口连接场景
  • 所有方案均需HTTPS环境(本地开发localhost不受限制)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:36:24