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

如何通过HTML表单向Node.js Express正确发送对象数组?

问题:如何通过Pug表单向Node.js/Express正确发送对象数组?

我用Pug写了一个HTML表单,想向Node.js/Express后端发送对象数组:

each val in [1, 2]
    div(class = "row")
        div(class= "col")
            select(class="form-select" name = "items[][service]")
                each service in services
                    option(value=service._id) #{service.name}                
        div(class= "col")
            input(type="text" name="items[][description]" class='form-control mb-4' placeholder="Description")
        div(class= "col")
            input(type="text" name="items[][amount]" class='form-control mb-4' placeholder="QTY")
        div(class= "col")
            input(type="text" name="items[][price]" class='form-control mb-4' placeholder="Price")
        div(class= "col")
            input(type="text" name="items[][subtotal]" class='form-control mb-4' placeholder="Subtotal")

我的Express配置(使用body-parser)如下:

const app = Express();
app.use(cookieParser());
app.set("view engine", "pug");
app.use(json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use("/admin", adminRouter);
set("strictQuery", false);
set("autoCreate", false);
app.listen(process.env.PORT || 8000);

但打印req.body后得到的结构不符合预期,所有同名字段都被塞进了数组:

items: [
    {
      service: [Array],
      description: [Array],
      amount: [Array],
      price: [Array],
      subtotal: [Array]
    }
]

我试过硬编码数组索引(比如items[0].service),但也没成功,请问正确的发送方式是什么?


解决方案

问题出在表单字段的name属性命名上:当前用items[][service]这种写法时,每个字段都会被单独追加到items数组的新元素里,最终导致所有同类型字段被合并成数组,而非按行分组为对象。

1. 修改Pug模板的字段命名

需要让同一行的所有字段共享同一个数组索引,这样body-parser会自动把它们分组为同一个对象。修改循环逻辑,使用循环的索引来指定数组位置:

each val, index in [1, 2]
    div(class = "row")
        div(class= "col")
            select(class="form-select" name = `items[${index}].service`)
                each service in services
                    option(value=service._id) #{service.name}                
        div(class= "col")
            input(type="text" name=`items[${index}].description` class='form-control mb-4' placeholder="Description")
        div(class= "col")
            input(type="text" name=`items[${index}].amount` class='form-control mb-4' placeholder="QTY")
        div(class= "col")
            input(type="text" name=`items[${index}].price` class='form-control mb-4' placeholder="Price")
        div(class= "col")
            input(type="text" name=`items[${index}].subtotal` class='form-control mb-4' placeholder="Subtotal")

这里用index(从0开始)作为数组的索引,同一行的所有字段都指向items[index]下的属性,提交后就能正确按行分组为对象。

2. 确认Express配置正确性

你的Express配置已经满足要求:必须保持bodyParser.urlencoded({ extended: true })的配置,因为extended: true允许解析嵌套的对象结构,这是正确解析数组对象的前提。

3. 验证结果

修改后,req.body的结构会变成预期的对象数组:

items: [
    {
        service: "xxx",
        description: "xxx",
        amount: "xxx",
        price: "xxx",
        subtotal: "xxx"
    },
    {
        service: "xxx",
        description: "xxx",
        amount: "xxx",
        price: "xxx",
        subtotal: "xxx"
    }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:46:35