NodeJS Post方法在Postman中运行良好,但当我尝试在React中使用Axios时,会出现一些错误

xfb7svmp  于 2023-06-29  发布在  Node.js
关注(0)|答案(1)|浏览(155)

我使用node.js,express,multer。要上传关于产品和文件的数据,首先在数据库中创建产品,然后我将文件上传到AWS S3并获取URL并将它们保存在名为imagenes_${productname}的表中。当我使用 Postman 一切都很好,postman request with data
这是我与postman一起使用的函数

const addProduct = async (req, res) => {

    // req.files contains an array of uploaded files

    const files = req.files;
    const urls = [];

    const precio_final = parseInt(req.body.precio)
    const product = req.body.product;
    let q = '';
    let values = [];


    try {
        for (const file of files) {
            const fileStream = fs.createReadStream(file.path);
            const folderName = product + "/";
            const key = folderName + file.originalname;
            const params = {
                Bucket: 'pisos-parador-colombia',
                Key: key,
                Body: fileStream
            };

            const command = new PutObjectCommand(params);
            await s3Client.send(command);

            // File uploaded successfully
            const fileUrl = `https://pisos-parador-colombia.s3.us-east-2.amazonaws.com/${key}`;
            urls.push(fileUrl);
        }
        if (product === "pisos_laminados" || product === "pisos_estructurados") {
            q = `INSERT INTO ${product} (titulo,precio,descripcion, trafico, grosor, junta , medidas) VALUES (?)`

            values = [
                req.body.titulo,
                precio_final,
                req.body.descripcion,
                req.body.trafico,
                req.body.grosor,
                req.body.junta,
                req.body.medidas
            ]

        }
        else {
            q = `INSERT INTO ${product} (titulo,precio,descripcion) VALUES (?)`

            values = [
                req.body.titulo,
                precio_final,
                req.body.descripcion,

            ]

        }

        db.query(q, [values], (err, data) => {
            if (err) return res.json(err)

            console.log("product has been created succesfully!");
            const laminateFloorId = data.insertId;

            // Store the URLs in the images_laminatefloors table with the laminate_floor_id
            for (const url of urls) {
                const imageValues = [url, laminateFloorId];
                const imageQuery = `INSERT INTO imagenes_${product} (image_url, product_id) VALUES (?, ?)`;
                db.query(imageQuery, imageValues, (err, imageData) => {
                    if (err) console.error(err);
                    else console.log('Image URL has been stored successfully!');
                });
            }

        })

        res.status(200).send("everything added succesfully");
    } catch (err) {
        console.error("este es el error" + err.message());
        res.status(500).send('Failed to upload files');
    }

}

module.exports = addProduct;

但是当我使用axios并传递相同的数据时,它会给我这个错误

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:399:5)
    at ServerResponse.setHeader (node:_http_outgoing:645:11)
    at ServerResponse.header (/Users/danielmonroy/Desktop/pisos_parador_sql/backend/node_modules/express/lib/response.js:794:10)
    at ServerResponse.send (/Users/danielmonroy/Desktop/pisos_parador_sql/backend/node_modules/express/lib/response.js:174:12)
    at ServerResponse.json (/Users/danielmonroy/Desktop/pisos_parador_sql/backend/node_modules/express/lib/response.js:278:15)
    at Query.<anonymous> (/Users/danielmonroy/Desktop/pisos_parador_sql/backend/controllers/addProduct.js:72:33)
    at Query.<anonymous> (/Users/danielmonroy/Desktop/pisos_parador_sql/backend/node_modules/mysql/lib/Connection.js:526:10)
    at Query._callback (/Users/danielmonroy/Desktop/pisos_parador_sql/backend/node_modules/mysql/lib/Connection.js:488:16)
    at Sequence.end (/Users/danielmonroy/Desktop/pisos_parador_sql/backend/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
    at Query.ErrorPacket (/Users/danielmonroy/Desktop/pisos_parador_sql/backend/node_modules/mysql/lib/protocol/sequences/Query.js:92:8) {
  code: 'ERR_HTTP_HEADERS_SENT'
}

我不知道我的代码有什么问题。使用Postman时一切正常,但当我使用Axios时,它给了我上面的错误。

w8rqjzmb

w8rqjzmb1#

我能看到的问题...
1.如果您的查询出错,则表示您正在尝试发送两个响应。这是 “header already sent” 错误的来源。

if (err) return res.json(err)

res.status(200).send("everything added succesfully");

query()回调返回不会停止其余代码的运行
1.不需要嵌套[values]。你只做了一次插入
考虑到这一点,我建议您使用以下

try {
  // upload to S3, create `q` and `values`, etc...

  db.query(q, values, (err, data) => {
    if (err) {
      return res.status(500).send(err);
    }

    // ...

    res.status(200).send("everything added succesfully");
  });
} catch (err) {
  res.status(500).send("Failed to upload files");
}

至于为什么它适用于Postman而不适用于Axios,我只能想象你为multipart/form-data错误地构建了请求体,这导致一些req.body值不正确,你的查询失败。
为了混合文件和其他数据,您需要分别appendset每个属性。比如说,

const fd = new FormData();
// add your files
for (const file of someFileInput.files) {
  fd.append("files", file);
}

// add other data
fd.append("product", "pisos_laminados");
fd.append("titulo", "roble");
fd.append("precio", "100,000");
// etc

axios.post("http://localhost:5000/api/addProduct", fd);

相关问题