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

通过AngularJS调用Chrome WebUSB API连接热敏打印机遇问题求助

我来帮你搞定AngularJS里调用WebUSB连接ESC/POS热敏打印机的问题!下面是适配AngularJS生态的完整解决方案,把原生JS的逻辑转化为符合AngularJS MVVM模式的实现:

在AngularJS中实现WebUSB API连接ESC/POS打印机

核心思路

AngularJS的核心是分离业务逻辑与DOM操作,所以我们会把WebUSB相关的设备处理逻辑封装成可复用的服务,再在控制器里调用服务,用AngularJS的数据绑定来管理按钮状态,彻底告别原生JS直接操作DOM的写法。

步骤1:封装WebUSB打印机服务

先创建一个专门的服务,把设备查找、连接、通信的逻辑都放这里,方便后续在多个控制器里复用:

angular.module('yourAppModule') // 替换成你的项目模块名
  .service('UsbPrinterService', function() {
    // 替换成你的打印机厂商ID和产品ID(十六进制格式)
    const VENDOR_ID = 0xXXXX;
    const PRODUCT_ID = 0xXXXX;

    // 获取已连接的打印机设备
    this.getConnectedDevices = async function() {
      try {
        return await navigator.usb.getDevices({
          filters: [{ vendorId: VENDOR_ID, productId: PRODUCT_ID }]
        });
      } catch (error) {
        console.error('获取已连接设备失败:', error);
        throw error;
      }
    };

    // 请求用户选择打印机(弹出设备选择框)
    this.requestDevice = async function() {
      try {
        return await navigator.usb.requestDevice({
          filters: [{ vendorId: VENDOR_ID, productId: PRODUCT_ID }]
        });
      } catch (error) {
        console.error('请求设备连接失败:', error);
        throw error;
      }
    };

    // 打开设备并配置接口(ESC/POS打印机通用配置)
    this.openDevice = async function(device) {
      try {
        await device.open();
        await device.selectConfiguration(1); // 大多数打印机用配置1
        await device.claimInterface(0); // 大多数打印机用接口0
        return device;
      } catch (error) {
        console.error('打开设备失败:', error);
        throw error;
      }
    };

    // 发送ESC/POS打印指令(扩展功能)
    this.sendPrintData = async function(device, printData) {
      try {
        // 输出端点通常为0x01,输入端点为0x81,可根据打印机说明书调整
        await device.transferOut(0x01, printData);
        console.log("打印数据发送成功");
      } catch (error) {
        console.error('发送打印数据失败:', error);
        throw error;
      }
    };
  });

步骤2:在控制器中调用服务

接下来在控制器里注入服务,处理按钮点击事件,用$scope管理连接状态,完全用AngularJS的数据绑定替代原生DOM操作:

<!-- 你的页面视图 -->
<div ng-controller="PrinterController">
  <button 
    ng-click="connectPrinter()" 
    ng-disabled="isConnecting"
  >
    {{ isConnected ? '已连接打印机' : '连接打印机' }}
  </button>

  <!-- 可选:打印测试按钮 -->
  <button 
    ng-click="printTest()" 
    ng-disabled="!isConnected"
    style="margin-left:10px;"
  >
    打印测试
  </button>
</div>
angular.module('yourAppModule')
  .controller('PrinterController', function($scope, UsbPrinterService) {
    $scope.isConnected = false;
    $scope.isConnecting = false;
    $scope.connectedDevice = null;

    // 页面初始化时检查是否有已连接的打印机
    $scope.init = async function() {
      try {
        const devices = await UsbPrinterService.getConnectedDevices();
        if (devices.length > 0) {
          $scope.connectedDevice = devices[0];
          $scope.isConnected = true;
          $scope.$apply(); // 异步操作后手动触发AngularJS视图更新
        }
      } catch (error) {
        console.error('初始化检查设备失败:', error);
      }
    };

    // 连接打印机的核心方法
    $scope.connectPrinter = async function() {
      $scope.isConnecting = true;
      $scope.$apply(); // 立即更新按钮状态

      try {
        let targetDevice;
        // 先检查是否已有已连接的设备
        const existingDevices = await UsbPrinterService.getConnectedDevices();
        if (existingDevices.length > 0) {
          targetDevice = existingDevices[0];
        } else {
          // 没有已连接设备,请求用户选择
          targetDevice = await UsbPrinterService.requestDevice();
        }

        // 打开并配置设备
        await UsbPrinterService.openDevice(targetDevice);
        $scope.connectedDevice = targetDevice;
        $scope.isConnected = true;
        alert('打印机连接成功!');
      } catch (error) {
        alert(`连接失败:${error.message}`);
      } finally {
        $scope.isConnecting = false;
        $scope.$apply(); // 恢复按钮状态
      }
    };

    // 打印测试内容(扩展功能)
    $scope.printTest = async function() {
      if (!$scope.isConnected) return;
      // 转成ESC/POS支持的字节数据,这里打印测试文本+换行
      const testText = new TextEncoder().encode('测试打印内容\n');
      await UsbPrinterService.sendPrintData($scope.connectedDevice, testText);
    };

    // 页面加载时执行初始化
    $scope.init();
  });

关键注意事项

  • 异步操作与$apply():WebUSB API是异步的,AngularJS无法自动检测异步操作后的变量变化,所以需要手动调用$scope.$apply()触发视图更新。
  • 环境要求:WebUSB API只能在HTTPS环境下使用(localhost除外),所以测试或部署时要确保站点是HTTPS协议。
  • 设备参数适配:不同品牌的ESC/POS打印机的配置接口、端点可能不同,需要根据打印机的官方说明书调整selectConfiguration、claimInterface和端点参数。
  • 错误处理:一定要保留完整的错误捕获逻辑,覆盖用户拒绝设备访问、设备断开、通信失败等场景,给用户明确的提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:55:33