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

Express路由POST参数未正确映射至Producto对象字段问题

问题:Express路由POST参数全部存入单个对象键中

我正在构建一个Express路由,希望通过客户端POST请求提交的数据将对象存入数组。但实际情况是,客户端输入的所有参数都被存入类构造函数定义的其中一个对象键(nombre)中,而非分配到各自对应的键。

用到的代码

服务器代码

const express = require('express')
const fs = require('fs')
const app = express()
const routeCarrito = require('./routers/routerCarritos.js')
const routeProducto = require('./routers/routerProductos.js')

app.set('views', './views')
app.set('view engine', 'pug')

app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.use('/api/productos', routeProducto)
app.use('/api/carrito', routeCarrito)

const PORT = 8080
const server = app.listen(PORT, () => {
    console.log(`El servidor esta escuchando en el puerto: ${server.address().port}`)
})
server.on('error', error => console.log(`Error en el servidor ${error}`))

路由代码(含Producto类)

const express = require('express')
const fs = require('fs')
const routeProducto = express.Router()
routeProducto.use(express.json())
routeProducto.use(express.urlencoded({extended: true}))

class Producto{
    constructor(id, timestamp, nombre, descripcion, codigo, urlFoto, precio, stock){
        this.id = id;
        this.timestamp = timestamp;
        this.nombre = nombre;
        this.descripcion = descripcion;
        this.precio = Number;
        this.urlFoto = urlFoto;
        this.codigo = codigo;
        this.stock = stock;
    }

    //Receives a product, saves it to the array file and returns the object's assigned id.
    save(nombre,descripcion,codigo,urlFoto,precio){
        fs.readFile('./arrays/productos.txt', 'utf-8', (error, contenido) => {
            if (error){
                console.log(error);
            } else {
                let productos = JSON.parse(contenido)
                let id = 1
                productos.map(producto => {
                    if(producto.id != null){
                        id++
                    }                    
                })
                let timestamp = new Date().toLocaleString()
                let stock = 1
                productos.map(producto => {
                    if(producto.stock != null){
                        stock++
                    }                    
                })
                let productoPush = {id, timestamp, nombre, descripcion, codigo, urlFoto, precio, stock}
                productos.push(productoPush)
                fs.promises.writeFile('./arrays/productos.txt', JSON.stringify(productos, ',', 2))
                    .then(() => console.log(`Producto guardado, su id es ${id}`))
                    .catch( error => console.log(error))
                }          
            });
    }
}

let productos = [];
const producto = new Producto();

routeProducto.post('/', (req, res) => {
    producto.save(req.body)
    res.send(`El producto "${req.body.nombre}" ha sido agregado al listado.`)
});

module.exports = routeProducto;

运行前需要一个包含空数组的productos.txt文件。


错误原因

核心问题出在save()方法的参数传递与接收逻辑:

  • save()方法定义的是多个独立参数(nombre,descripcion,codigo,urlFoto,precio),但调用时传入的是整个req.body对象。这导致第一个参数nombre接收了完整的请求体对象,后续参数全为undefined,最终存入文件的对象只有nombre键有值。
  • 构造函数中this.precio = Number;是错误写法,应为接收传入的precio值,而非赋值Number构造函数。
  • 生成id和stock的map遍历逻辑冗余且易出错,会导致id和stock数值异常递增。

修复后的代码

修改后的Producto类与路由逻辑

const express = require('express')
const fs = require('fs')
const routeProducto = express.Router()
routeProducto.use(express.json())
routeProducto.use(express.urlencoded({extended: true}))

class Producto{
    constructor(id, timestamp, nombre, descripcion, codigo, urlFoto, precio, stock){
        this.id = id;
        this.timestamp = timestamp;
        this.nombre = nombre;
        this.descripcion = descripcion;
        this.precio = precio; // 修复:赋值传入的precio值
        this.urlFoto = urlFoto;
        this.codigo = codigo;
        this.stock = stock;
    }

    // 改为接收单个对象参数,匹配req.body的传递方式
    save(productData){
        fs.readFile('./arrays/productos.txt', 'utf-8', (error, contenido) => {
            if (error){
                console.log(error);
            } else {
                let productos = JSON.parse(contenido)
                // 简化id生成:直接用数组长度+1,高效准确
                let id = productos.length + 1
                let timestamp = new Date().toLocaleString()
                // 可从请求体取stock,无值则默认1
                let stock = productData.stock || 1
                // 用构造函数创建对象,确保属性正确赋值
                let productoPush = new Producto(
                    id, 
                    timestamp, 
                    productData.nombre, 
                    productData.descripcion, 
                    productData.codigo, 
                    productData.urlFoto, 
                    Number(productData.precio), // 确保价格为数字类型
                    stock
                )
                productos.push(productoPush)
                fs.promises.writeFile('./arrays/productos.txt', JSON.stringify(productos, null, 2))
                    .then(() => console.log(`Producto guardado, su id es ${id}`))
                    .catch( error => console.log(error))
                }          
            });
    }
}

const producto = new Producto();

routeProducto.post('/', (req, res) => {
    producto.save(req.body) // 传入完整req.body对象,与修改后的save方法匹配
    res.send(`El producto "${req.body.nombre}" ha sido agregado al listado.`)
});

module.exports = routeProducto;

补充说明

  1. 调整save()方法参数为单个对象,适配Express中req.body的传递逻辑,避免参数不匹配问题。
  2. 用类构造函数创建新对象,确保所有属性正确映射。
  3. 对precio做类型转换,保证存入数值类型而非字符串。
  4. 简化id生成逻辑,避免冗余遍历导致的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:01:01