如何阻止Node.js将带数字键的嵌套对象转为数组?
如何阻止嵌套对象的数字键被Node.js服务端转换为数组?
当向Node.js服务端发送内部包含数字键的嵌套对象时,该对象会被自动转换为数组,以下是解决方法:
问题复现
客户端代码
$.ajax({ url : `/cctool/report`, method : "PUT", data : { new : { 10 : "Test", 20 : "Hello", } } });
服务端代码
router.put("/cctool/report", (request, response) => { console.log(request.body); });
输出结果
{ new: [ 'Test', 'Hello' ] }
当前服务端配置
const express = require('express'); const CookieParser = require('cookie-parser'); const Sessions = require('express-session'); const crypto = require('crypto'); const router = express.Router(); router.use(express.json()); router.use(express.urlencoded({extended : true})); router.use(CookieParser()); router.use( Sessions({ secret : crypto.randomBytes(64).toString('hex'), saveUninitialized : false, cookie : {maxAge : 1000 * 60 * 60 * 8}, // 8 hours resave : false }));
解决方法
方案一:客户端发送JSON格式数据
修改AJAX请求,明确以JSON格式发送数据,避免表单序列化带来的歧义:
$.ajax({ url: `/cctool/report`, method: "PUT", contentType: "application/json", data: JSON.stringify({ new: { 10: "Test", 20: "Hello", } }) });
服务端的express.json()中间件会直接解析JSON数据,保留原对象的键值对结构。
方案二:修改服务端解析规则
如果必须使用表单编码格式,可调整express.urlencoded的配置,关闭qs库自动解析数组的行为:
router.use(express.urlencoded({ extended: true, parser: { parseArrays: false } }));
此配置会让qs库将带数字键的嵌套结构解析为对象,而非数组。
原因说明
问题源于jQuery默认以application/x-www-form-urlencoded格式发送数据,会将嵌套对象序列化为new[10]=Test&new[20]=Hello。而express.urlencoded在extended: true时使用的qs库,默认会把这种数字下标格式解析为数组。上述两种方案分别从发送格式和解析规则入手,解决了转换问题。
内容的提问来源于stack exchange,提问作者Tim Graf
相关产品推荐
相关产品推荐

