如何在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
相关产品推荐
相关产品推荐

