Express中res.send发送Map对象仅返回空对象{}如何解决
问题现象
合作开发游戏过程中,Express接口需要返回存储业务数据的Map对象,调用res.send(userData)发送响应时,客户端始终收到空对象{},无法获取实际存储的内容。
经排查确认:
- 业务代码逻辑无异常,控制台执行
console.log(userData)可正常输出完整Map结构 - 更换请求客户端无法解决该异常
相关问题代码:
router.get("/list", async (req, res) => { try { const users = await userCollection.find(); accessedListEmbed(req); let userData = new Map(); users.forEach((user) => userData.set(user.userName, user.status)); res.send(userData); console.log(userData); } catch (error) { res.send("unknown"); } });
根本原因
Express的res.send方法发送对象类型响应时,会默认调用JSON.stringify()做序列化处理,而原生JSON序列化规则不支持ES6 Map结构:Map的键值对不会被识别为对象的可枚举属性,序列化后直接输出空对象{}。
控制台能正常打印Map是因为Node.js的console打印逻辑对Map做了专门的格式化处理,和JSON序列化逻辑无关,这也是该问题容易被误判的核心原因。
修复方案
根据业务场景选择一种即可:
- 转普通对象返回:适合前端只需要键值对映射、不需要还原Map结构的场景,直接用
Object.fromEntries()转换即可,改造成本最低res.send(Object.fromEntries(userData)) - 转二维数组返回:适合前端需要还原Map结构的场景,把Map转成
[ [key1, value1], [key2, value2] ]格式的数组返回,前端拿到后可以直接用new Map(响应数据)还原res.send(Array.from(userData)) // 也可以用展开运算符写法:res.send([...userData])
修复后参考代码
router.get("/list", async (req, res) => { try { const users = await userCollection.find(); accessedListEmbed(req); let userData = new Map(); users.forEach((user) => userData.set(user.userName, user.status)); // Map转普通对象后再序列化返回 res.send(Object.fromEntries(userData)); console.log(userData); } catch (error) { res.send("unknown"); } });
内容的提问来源于stack exchange,提问作者DNAScanner
相关产品推荐
相关产品推荐

