Почему я получаю эту НЕОЖИДАННУЮ ошибку HTTP в NodeJS

#javascript #mysql #node.js #http-headers #http-error

#javascript #mysql #node.js #http-заголовки #http-ошибка

Вопрос:

Итак, ребята, я настраиваю свой сервер в NodeJS для веб-сайта электронной коммерции. Но я столкнулся с ошибкой при попытке реализовать метод «Order».

Сначала подключение к базе данных mysql :

 let mysql = require('mysql')

let connection = mysql.createConnection({

    host: 'localhost',
    user: 'root',
    password: '',
    database: 'ecom_new'

})

connection.connect()

module.exports = connection
  

Тогда в моих моделях есть класс Client, который содержит следующий метод :

 static order(orderData, callbackfn) {

        orderData.products.map((product) => {

            connection.query(`INSERT INTO orders SET
                product_name = ?, owner = ?, quantity = ?, price = ?, client_name = ?, client_phone = ?, client_address = ?`,
                [product.name, product.owner, product.count,product.price, orderData.clientName, 
                orderData.clientPhone, orderData.clientLoc], (err, result) => {

                    if (err) {

                        callbackfn(err)

                    } else {

                        callbackfn(null, result)

                    }

                })

        })


    }
  

Параметр orderData в методе order() представляет собой JSON, отправленный из интерфейса, который выглядит следующим образом:

 {
    "products": [
        {"name": "Item 1", "owner": "Clint", "count": 1, "price": 150},
        {"name": "Item 2", "owner": "Steve", "count": 3, "price": 350},
        {"name": "Item 3", "owner": "Bruce", "count": 6, "price": 110}
     ],

    "clientName": "Tony Stark",
    "clientPhone": "111111",
    "clientLoc": "Malibu"
}
  

И, наконец, маршрут, который обрабатывает этот запрос, закодирован следующим образом :

 router.post('/client/order', (req, res) => {


    Client.order(req.body, (err, result) => {

        if (err) {

            res.json({RequestResult: 'ERROR', Message: err['sqlMessage']})

        } else {

            res.json({RequestResult: 'SUCCESS', Message: 'New order placed successfully'})

        }

    })


})
  

Это работает просто отлично, когда я пытаюсь (один раз) разместить заказ с моего интерфейса (и Postman).

Но проблема в том, что всякий раз, когда я пытаюсь (снова) разместить заказ, я получаю ошибку [ERR_HTTP_HEADERS_SENT] . Похоже, я могу разместить заказ только один раз, что является бессмыслицей.

Я действительно не знаю, что не так, и это мешает мне перейти к другим проблемам моего проекта, нужна помощь.

Спасибо

Комментарии:

1. Можете ли вы добавить console.log() s в свой код, чтобы выяснить, как далеко заходит выполнение и какие значения на самом деле имеют переменные?

2. похоже, что ваш серверный код пытается ответить на запрос более одного раза. как только ответ отправлен, вы не можете этого сделать. я не вижу кода, который вызывает ее здесь, но это то, что вам нужно выяснить.

3. Questor прибил это, однако мне интересно, почему код работает в первый раз и завершается сбоем только при последующих запусках? С вашим текущим кодом вы должны быть в состоянии надежно воспроизвести ошибку, если вы отправляете два или более продуктов (также, просто для удобства чтения, вы должны использовать forEach вместо map , если вы не используете измененный массив)

4. @ChrisG Да, он, конечно, сделал, это тоже было моей главной заботой, это странное поведение. (Хорошо, я собираюсь это сделать, спасибо :))

Ответ №1:

Я думаю, проблема в том, что вы перебираете продукты с помощью orderData.products.map((product) => {... и для каждого продукта вызываете callbackfn который, в свою очередь, вызывает res.json({...}) . Итак, для каждого продукта вызывается res.json({...}) , но я думаю, что вам разрешено вызывать его только один раз за запрос.

Попробуйте что-то подобное в классе Client:

 static order(orderData) {
  return Promise.all(orderData.products.map((product) => {
    return new Promise((resolve, reject) => {
      //run query
      if (err) reject(err)
      else resolve()
    })
  }))
}
  

теперь вы можете использовать эту функцию следующим образом:

 Client.order(req.body)
  .then(() => res.json({ RequestResult: 'SUCCESS', Message: 'New order placed successfully' }))
  .catch(err => res.json({ RequestResult: 'ERROR', Message: err['sqlMessage'] }))
  

Комментарии:

1. Привет, @questor , спасибо за объяснение в начале, после прочтения логика моего кода стала более понятной. И ваш код работает, я только что попробовал это. Я действительно новичок в Promises и прочем, но я собираюсь потратить время и попытаться прочитать понять код в деталях. Большое спасибо, вы решили мою проблему!!