核心功能
扫描
列出扫描仪、读能力、发起扫描、桌面确认与取回成品。
最后更新
扫描与打印是相互独立的能力:扫描失败、设备忙碌都不会影响打印。
权限与确认
扫描权限不在默认授予范围内,需要单独申请:scanner.read(看设备)与
scan.run(发起扫描)。scan.run 每次扫描都会在桌面端弹出确认,
用户同意后才扫。无头服务默认直接拒绝。
完整流程
await client.ensureAuthorized(['scanner.read', 'scan.run']);
const { scanners } = await client.scannerList();
const scanner = scanners[0];
if (!scanner) throw new Error('没有可用扫描仪');
// 可选:先确认参数在设备上会被如何处理
const check = await client.scanValidate(scanner.scannerId, {
source: 'platen', // platen 平板 / feeder 进纸器
format: 'image/jpeg',
});
// 发起扫描并等待终态(含用户确认的时间)
const job = await client.scan({
scannerId: scanner.scannerId,
options: { source: 'platen', format: 'image/jpeg' },
title: '身份证正面',
});
for (const page of job.pages) {
const blob = await client.fetchScanPage(job.scanId, page.index, page.downloadTicket);
// 用这个 Blob:URL.createObjectURL(blob) 预览,或上传到你的后端
}scan() 会一直等到用户在桌面端确认、拒绝或超时(默认 120 秒)。用户拒绝得到
SCAN_CONSENT_DENIED,超时得到 SCAN_CONSENT_TIMEOUT。
读设备能力与状态
const caps = await client.scannerCapabilities(scannerId);
// 进纸来源 × 分辨率 × 颜色模式 × 输出格式 × 尺寸
const status = await client.scannerStatus(scannerId);和打印一样,只提供能力清单里有的选项。参数会经过与打印相同的能力校验,
不支持的取值会降级并给警告;用 scanValidate 可以在真正扫描前拿到结果。
取回成品
成品字节不走 WebSocket,而是同端口的 HTTP 下载:
const blob = await client.fetchScanPage(scanId, pageIndex, page.downloadTicket);downloadTicket是页元数据里带的短时票据,只发给发起扫描的那个站点; 不传则自动使用当前授权令牌。- 其他来源拿不到这些文件,只会得到
SCAN_NOT_FOUND,不泄露作业是否存在。 - 成品只在本机临时保留(默认 10 分钟、总量默认 512 MiB),重启即清空。
过期或被清理后返回
CONTENT_EXPIRED,所以要及时下载。
控制台「设置 → 缓存 → 扫描件缓存」可以查看、另存为、删除或清空已完成的扫描件。
取消与查询
await client.scanCancel(scanId); // 取消进行中的扫描
const list = await client.scanList(20); // 本站点的扫描记录
const job = await client.scanStatus(scanId);常见错误
| 错误码 | 含义 |
|---|---|
PERMISSION_DENIED | 没申请 scanner.read / scan.run |
SCAN_DISABLED | 设置里关闭了扫描 |
SCAN_CONSENT_DENIED / SCAN_CONSENT_TIMEOUT | 用户拒绝,或确认超时 |
SCANNER_BUSY | 设备被占用,稍后重试 |
UNSUPPORTED_SCAN_OPTION | 参数超出设备能力 |
SCAN_SOURCE_EMPTY | 进纸器没纸 |
SCAN_TOO_LARGE / SCAN_TIMEOUT | 页数、体积或时长超限 |
CONTENT_EXPIRED | 成品已过期或被清理 |