WebSocket 收到二进制却当字符串,怎样核对 UTF-8 解码边界
WebSocket文本消息必须是有效UTF-8,二进制消息的格式则由业务协议决定。浏览器收到ArrayBuffer或Blob时不能直接假设它就是JSON字符串;先依据接口契约确认编码,再使用严格解码。中文的多字节序列若跨分片,逐片无状态解码会把合法消息误判成乱码。
环境和证据范围
附件只处理已提取的payload字节,比较完整消息解码与增量UTF-8解码。未实现WebSocket掩码、压缩或真实浏览器binaryType行为。二进制样例若并非约定的UTF-8,本来就不应按文本读取;不能把任意二进制载荷强转成字符串来“修复”。
核对顺序
-
先记录消息类型:text还是binary,以及客户端拿到的是字符串、ArrayBuffer还是Blob。二进制如果是图像或私有结构,应该交相应解析器,不能因内容里偶尔有大括号就认定JSON。
-
对约定为UTF-8的完整payload使用严格解码,失败时保留hex、长度和错误偏移,不使用替换字符悄悄继续解析。无效文本应按规范和库能力处理,不能把损坏内容传给设备路由。
-
若观察点位于片段层,使用支持流式状态的解码器或先重组完整消息,再做最终解码检查。最后一段必须标记结束,以便发现被截断的多字节序列。
-
解码成功后再做JSON语法和业务结构校验,三层错误分开记录。修复文本编码不意味着设备字段正确;JSON中的数字、布尔类型和关联编号仍要照合同验证。
可复算的输入与预期
“厅”的UTF-8为e5 8e 85,附件把它拆成e5和8e85两段,增量解码得到“厅”;ff严格解码失败;binary opcode=2且没有文本契约时返回“交业务二进制解析器”。脚本实际执行解码与异常捕获,不将这些字节发到网络。
下载与现场记录
下载本题合成输入与预期JSON、离线只读核验脚本和现场空白记录CSV。放在同一目录,用 Python 3 运行 python verify.py,逐项计算或解析后与预期比较,失败会显示差异。
现场字段包括 opcode、delivered_type、payload_hex、declared_encoding、decode_error_offset、json_result。合成样例保持原样,实测另存并填写型号、版本、证据路径,未采集处留空。本地核验不代表真实设备、代理、浏览器或长期稳定性已测。
失败分支与移交
直接对ArrayBuffer调用toString得到的可能是对象描述,使用String.fromCharCode逐字节拼中文也会产生错误。替换字符�会损坏设备名和签名字段,禁止把“看起来能显示”当验证通过。若只在浏览器失败,应保留原始字节并比较服务端发送与库交付类型。
移交时注明消息类型、业务编码、binaryType设置、是否压缩、最大长度和失败处理。真实浏览器还要测试Blob异步读取顺序与连接关闭时的未完成消息,本文没有这些实测;下载件只证明指定字节样例按严格UTF-8规则能复算。
基础背景可看WebSocket 展厅实时控制实现深度。若字节来自帧级日志,先按消息边界重组,见WebSocket 一条 JSON 被分成多帧,怎样验消息边界。更多资料在设备协议库。
需要接入中控时,可对照SoftControl设备联动需求核实适配范围;独立校验方法是否纳入交付需逐项约定。
一级资料
核对日期:2026-10-24。规范定义与本文应用约定分开,示例门限及脚本不自动代表产品原生能力。
相关阅读
留言讨论
评论发布后会被人工复核,违规内容将被删除。
如果发表没有反应,可以前往联系我们告诉我们。