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

为何Node.js通过Socket.io发送JSON需两次JSON.parse才能转对象?

问题原因分析与解决方案

兄弟,我太懂这种困惑了!你这问题核心就是服务器端重复做了JSON序列化,导致发送的内容是「套了一层的JSON字符串」,所以客户端得拆两层才能拿到对象。

为什么会需要两次JSON.parse?

咱们一步步捋清楚:

  1. 你定义的dataString本身已经是一个合法的JSON字符串了:
    '{"test": [ {"M": "A", ...} ]}'
    
  2. 但你又多做了一步JSON.stringify(dataString)——这会把这个JSON字符串再一次转成JSON格式的字符串:简单说就是给整个字符串套了双引号,还把里面所有的双引号都转义成了\",最终变成了客户端收到的带转义符的内容:
    "{\"test\": [ {\"M\": \"A\", ...} ]}\n"
    
  3. 客户端第一次调用JSON.parse,其实是把这个带转义的字符串还原成你最初写的dataString(也就是那个原始的JSON字符串);第二次调用才是把这个JSON字符串转成真正的JavaScript对象。

怎么解决?

直接去掉服务器端多余的JSON.stringify就行,给你两种更规范的写法:

方案一:直接发送原始JSON字符串

既然dataString已经是JSON格式的字符串了,直接发出去就行:

const dataString = '{"test": [ {"M": "A", "R": "e", "B": "e", "C": "e", "K": "e", "BD": "e", "CYC": "e"},{"M": "B", "R": "e", "B": "e", "C": "e", "K": "e", "BD": "e", "CYC": "e"}, {"M": "C", "R": "e", "B": "e", "C": "e", "K": "e", "BD": "e", "CYC": "e"},{"M": "D", "R": "e", "B": "e", "C": "e", "K": "e", "BD": "e", "CYC": "e"}]}';
socket.emit('test', dataString);

这种情况下客户端只需要一次JSON.parse就能拿到对象:

socket.on('test', function (message) {
  const transfer = JSON.parse(message);
  console.log(transfer.test); // 直接访问对象属性
});

方案二:先转成对象再发送(更推荐)

Socket.io本身会自动帮你序列化/反序列化JSON数据,所以更规范的做法是先把JSON字符串转成JavaScript对象,直接发送对象即可:

// 先把JSON字符串解析成对象
const dataObj = JSON.parse('{"test": [ {"M": "A", "R": "e", "B": "e", "C": "e", "K": "e", "BD": "e", "CYC": "e"},{"M": "B", "R": "e", "B": "e", "C": "e", "K": "e", "BD": "e", "CYC": "e"}, {"M": "C", "R": "e", "B": "e", "C": "e", "K": "e", "BD": "e", "CYC": "e"},{"M": "D", "R": "e", "B": "e", "C": "e", "K": "e", "BD": "e", "CYC": "e"}]}');
// 直接发送对象,Socket.io会自动处理序列化
socket.emit('test', dataObj);

这种情况下客户端连JSON.parse都不用写,收到的message直接就是对象:

socket.on('test', function (message) {
  console.log(message.test); // 直接用就行!
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:06:20