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

如何将第三方WebSocket返回的Uint8Array正确解码为可读字符串?

问题描述

我尝试解析第三方网站的WebSocket响应,该网站以Blob形式流式传输数据,我已将Blob转换为Uint8Array,其字符串化结果如下:

{"0":18,"1":196,"2":2,"3":10,"4":18,"5":78,"6":83,"7":69,"8":95,"9":73,"10":78,"11":68,"12":69,"13":88,"14":124,"15":78,"16":105,"17":102,"18":116,"19":121,"20":32,"21":53,"22":48,"23":18,"24":173,"25":2,"26":18,"27":170,"28":2,"29":18,"30":167,"31":2,"32":10,"33":25,"34":9,"35":102,"36":102,"37":102,"38":102,"39":150,"40":81,"41":210,"42":64,"43":16,"44":192,"45":160,"46":216,"47":192,"48":204,"49":48,"50":33,"51":51,"52":51,"53":51,"54":51,"55":131,"56":46,"57":210,"58":64,"59":18,"60":247,"61":1,"62":10,"63":47,"64":10,"65":2,"66":49,"67":100,"68":17,"69":205,"70":204,"71":204,"72":204,"73":108,"74":48,"75":210,"76":64,"77":25,"78":51,"79":51,"80":51,"81":51,"82":3,"83":96,"84":210,"85":64,"86":33,"87":51,"88":51,"89":51,"90":51,"91":35,"92":46,"93":210,"94":64,"95":41,"96":102,"97":102,"98":102,"99":102,"100":150,"101":81,"102":210,"103":64,"104":56,"105":192,"106":208,"107":156,"108":165,"109":204,"110":48,"111":10,"112":47,"113":10,"114":2,"115":73,"116":49,"117":17,"118":205,"119":204,"120":204,"121":204,"122":92,"123":91,"124":210,"125":64,"126":25,"127":205,"128":204,"129":204,"130":204,"131":92,"132":91,"133":210,"134":64,"135":33,"136":51,"137":51,"138":51,"139":51,"140":51,"141":85,"142":210,"143":64,"144":41,"145":205,"146":204,"147":204,"148":204,"149":60,"150":86,"151":210,"152":64,"153":56,"154":160,"155":221,"156":230,"157":191,"158":204,"159":48,"160":10,"161":47,"162":10,"163":2,"164":73,"165":49,"166":17,"167":0,"168":0,"169":0,"170":0,"171":16,"172":87,"173":210,"174":64,"175":25,"176":0,"177":0,"178":0,"179":0,"180":16,"181":87,"182":210,"183":64,"184":33,"185":0,"186":0,"187":0,"188":0,"189":16,"190":87,"191":210,"192":64,"193":41,"194":0,"195":0,"196":0,"197":0,"198":16,"199":87,"200":210,"201":64,"202":56,"203":128,"204":178,"205":234,"206":191,"207":204,"208":48,"209":10,"210":48,"211":10,"212":3,"213":73,"214":51,"215":48,"216":17,"217":154,"218":153,"219":153,"220":153,"221":121,"222":64,"223":210,"224":64,"225":25,"226":205,"227":204,"228":204,"229":204,"230":108,"231":83,"232":210,"233":64,"234":33,"235":154,"236":153,"237":153,"238":153,"239":201,"240":59,"241":210,"242":64,"243":41,"244":205,"245":204,"246":204,"247":204,"248":76,"249":83,"250":210,"251":64,"252":56,"253":160,"254":204,"255":197,"256":190,"257":204,"258":48,"259":10,"260":48,"261":10,"262":3,"263":73,"264":51,"265":48,"266":17,"267":154,"268":153,"269":153,"270":153,"271":137,"272":83,"273":210,"274":64,"275":25,"276":205,"277":204,"278":204,"279":204,"280":188,"281":94,"282":210,"283":64,"284":33,"285":0,"286":0,"287":0,"288":0,"289":64,"290":83,"291":210,"292":64,"293":41,"294":0,"295":0,"296":0,"297":0,"298":16,"299":87,"300":210,"301":64,"302":56,"303":224,"304":186,"305":179,"306":191,"307":204,"308":48,"309":33,"310":51,"311":51,"312":51,"313":51,"314":3,"315":96,"316":210,"317":64,"318":41,"319":51,"320":51,"321":51,"322":51,"323":179,"324":167,"325":205,"326":64,"327":24,"328":172,"329":172,"330":151,"331":203,"332":204,"333":48}

我用以下代码尝试解码这个Uint8Array:

let utf8decoder = new TextDecoder(); // 默认 'utf-8' 或 'utf8'
utf8decoder.decode(arr);

但解码结果里有大量乱码:

'\x12�\x02\n\x12NSE_INDEX|Nifty 50\x12�\x02\x12�\x02\x12�\x02\n\x19\tffff�Q�@\x10�����0!3333�.�@\x12�\x01\n/\n\x021d\x11����l0�@\x193333\x03`�@!3333#.�@)ffff�Q�@8�М��0\n/\n\x02I1\x11����\\[�@\x19����\\[�@!33333U�@)����<V�@8����0\n/\n\x02I1\x11\x00\x00\x00\x00\x10W�@\x19\x00\x00\x00\x00\x10W�@!\x00\x00\x00\x00\x10W�@)\x00\x00\x00\x00\x10W�@8����0\n0\n\x03I30\x11����y@�@\x19����lS�@!�����;�@)����LS�@8��ž�0\n0\n\x03I30\x11�����S�@\x19���̼^�@!\x00\x00\x00\x00@S�@)\x00\x00\x00\x00\x10W�@8ຳ��0!3333\x03`�@)3333���@\x18�����0'

请问如何正确解码这个Uint8Array得到可读字符串?

解决方案

这不是UTF-8编码的纯文本数据,而是**Protocol Buffers(protobuf)**格式的二进制数据——从解码结果里的\x12(protobuf的字段标识,代表长度限定的字符串类型,字段编号2)、\x0A(字段标识,代表重复字段或字符串类型,字段编号1)这类标识就能看出来,那些无法用UTF-8解析的字节其实是protobuf里的数值类型(比如浮点数、整数)。

要正确解析它,你需要:

  1. 获取该网站使用的protobuf .proto定义文件(如果无法直接获取,可以尝试通过已有的数据逆向推导,比如从解码出的NSE_INDEX|Nifty 50这类已知字段入手)。
  2. 使用JavaScript的protobuf库(比如protobufjs)来解析这个Uint8Array:
    • 安装依赖:npm install protobufjs
    • 示例代码:
      const protobuf = require("protobufjs");
      
      // 加载对应的.proto定义文件
      const root = protobuf.loadSync("your-proto-file.proto");
      // 查找对应的消息类型
      const MessageType = root.lookupType("YourMessage");
      
      // 解析Uint8Array
      const message = MessageType.decode(arr);
      // 转换为可读的JSON对象
      const plainObject = MessageType.toObject(message, {
        defaults: true,
        arrays: true,
        objects: true
      });
      
      console.log(plainObject);
      

如果暂时无法获取.proto文件,可以尝试用基于protobufjs的在线解析工具,把Uint8Array的字节数据导入,结合已知字段信息逆向推导结构。

内容的提问来源于stack exchange,提问作者Gracie williams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:11:36