通过XMLHttpRequest向Zebra标签打印机发数据存在数量限制问题求助
解决Zebra打印机批量打印超过24个标签时仅打印24个的问题
你的循环逻辑本身没问题,但异步请求的并发发送方式是导致这个问题的核心。用alert测试时,弹窗会阻塞循环,相当于给每个请求之间留足了打印机处理的时间;但直接发送XMLHttpRequest时,循环会在极短时间内发起所有请求,这会触发两个关键限制:
- 浏览器对同一域名的并发HTTP请求数限制(多数浏览器默认是6-8个),超出的请求会被排队甚至直接丢弃
- Zebra打印机的HTTP打印接口可能存在请求处理缓冲区或并发上限,短时间内接收太多请求会导致后续请求无法被正确处理
下面是两种可行的解决方案:
方案1:串行发送请求(最可靠)
把异步请求改成串行执行,等前一个标签的打印请求完成后,再发送下一个。用async/await改造后的代码如下:
$('#filterlabel').click(async function() { const ttllabels = parseInt($('#ttllabels').html()); // 转换为数字,避免字符串循环的意外问题 if (confirm(`Print ${ttllabels} address labels?`) !== true) { return; } for (let i = 0; i < ttllabels; i++) { const accdelno = $(`#accdelno-${i}`).val(); const custname = $(`#custname-${i}`).val(); const address1 = $(`#address1-${i}`).val(); const postcode = $(`#postcode-${i}`).val(); let y = 24; const qty = 1; let zpl = "^XA"; if (custname.length > 0) { zpl += `^FS^FO20,${y}^A0N,36,36^FD${custname}`; y += 40; } if (address1.length > 0) { zpl += `^FS^FO20,${y}^A0N,36,36^FD${address1}`; y += 40; } if (postcode.length > 0) { zpl += `^FS^FO20,${y}^A0N,36,36^FD${postcode}`; y += 40; } zpl += `^PQ${qty}^XZ`; // 封装请求为Promise,等待当前请求完成再执行下一次循环 await new Promise((resolve, reject) => { const request = new XMLHttpRequest(); request.open("POST", "http://192.168.88.202/pstprnt", true); request.setRequestHeader("Content-Length", zpl.length); request.onload = () => resolve(); request.onerror = () => reject(); request.send(zpl); }); } });
方案2:合并所有ZPL为一个请求(更高效)
把所有标签的ZPL内容合并成一个字符串,只发送一次请求。ZPL支持在单个指令流中包含多个标签,打印机会依次处理每个标签:
$('#filterlabel').click(function() { const ttllabels = parseInt($('#ttllabels').html()); if (confirm(`Print ${ttllabels} address labels?`) !== true) { return; } let fullZpl = ""; for (let i = 0; i < ttllabels; i++) { const accdelno = $(`#accdelno-${i}`).val(); const custname = $(`#custname-${i}`).val(); const address1 = $(`#address1-${i}`).val(); const postcode = $(`#postcode-${i}`).val(); let y = 24; const qty = 1; let zpl = "^XA"; if (custname.length > 0) { zpl += `^FS^FO20,${y}^A0N,36,36^FD${custname}`; y += 40; } if (address1.length > 0) { zpl += `^FS^FO20,${y}^A0N,36,36^FD${address1}`; y += 40; } if (postcode.length > 0) { zpl += `^FS^FO20,${y}^A0N,36,36^FD${postcode}`; y += 40; } zpl += `^PQ${qty}^XZ`; fullZpl += zpl; // 合并每个标签的ZPL指令 } // 发送一次合并后的完整请求 const request = new XMLHttpRequest(); request.open("POST", "http://192.168.88.202/pstprnt", true); request.setRequestHeader("Content-Length", fullZpl.length); request.send(fullZpl); });
额外注意事项
- 确保
ttllabels是数字类型:原代码中$('#ttllabels').html()返回的是字符串,直接用于循环可能出现意外行为,建议用parseInt转换 - 可以给请求添加
onerror事件处理,方便排查打印失败的具体情况
内容的提问来源于stack exchange,提问作者CR15 BRN
相关产品推荐
相关产品推荐

