网页 JavaScript 如何编码 gb2312

352 阅读1分钟

昨天学习打印机指令时,遇到中文乱码的问题。

解决方案

先说解决方案:

import { encodingIndexes } from "@zxing/text-encoding/es2015/encoding-indexes";
import { TextEncoder } from "@zxing/text-encoding";
// @ts-ignore
window.TextEncodingIndexes = { encodingIndexes: encodingIndexes };
// 如果没有引入 encodingIndexes,机会报错:Indexes missing. Did you forget to include encoding-indexes.js first?
// 当然,我这里是比较粗暴的做法,可能有更好的引入 encodingIndexes 的方法

const encoder = new TextEncoder("gb2312", {
	NONSTANDARD_allowLegacyEncoding: true,
});
const encoded = encoder.encode("中文");
console.log(encoded); // Uint8Array(2) [214, 208, buffer: ArrayBuffer(2), byteLength: 2, byteOffset: 0, length: 2, Symbol(Symbol.toStringTag): 'Uint8Array']

214 208 转为 16 进制为 D6 D0,查看 GB2312 编码表 D6D0

注意:引入 @zxing/text-encoding 后,包大小增加约 540KB

问题

打印英文不存乱码的问题。

打印机支持 gb2312 编码,从浏览发送数据到打印机,需要编码为 gb2312,如果发送到打印的字节数组是用 TextEncoder 的 encode("中") 编码出来,打印机打出的是 “涓 ”。

const encoder = new TextEncoder();
const encoded = encoder.encode(“中”);
console.log(encoded); // Uint8Array(3) [228, 184, 173, buffer: ArrayBuffer(3), byteLength: 3, byteOffset: 0, length: 3, Symbol(Symbol.toStringTag): 'Uint8Array']

228, 184, 173 转为 十六进制 E4 B8 AD,查 GB2312 编码表 E4 B8 -> AD 没有编码。

乱码的原因是:打印机支持 gb2312,但是接收到的却是 utf-8 编码的文字,所以就乱码了。

解决方法:统一两端的编码。

参考

developer.mozilla.org/zh-CN/docs/…

juejin.cn/post/684490…

github.com/zxing-js/te…

GB2312 编码表