发布到数据库时,我得到一个“发送错误后无法设置标头”

在这个问题中,我发布了完整的数据stream来完成销售,因为我不知道错误在哪里。 在我的应用程序中,在Checkout组件中调用一个名为handlePay()的函数,该函数又调用一个名为makeSale()的动作创build器。 makeSale()然后向router.js中的服务器发出一个POST请求,该请求将使用mongoose处理数据库中的这个销售。 从控制台读取错误

“/Users/marcushurney/Desktop/POS/node_modules/mongodb/lib/utils.js:98 process.nextTick(function(){throw err;}); ^

错误:发送后无法设置标题。“

我不确定这个错误是否存在于与router.js或前端其他地方的数据库进行通信的代码中。 前端的组件叫做Checkout.jsx,处理销售的function是handlePay(),其关联的动作创build者是makeSale()。

Checkout.jsx

handlePay: function() { var props = { user_id: this.props.activeUser._id, //This sale will belong to the user that is logged in (global state) items: [], //All the items in the cart will be added to the sale below (global state) total: this.props.cartTotal //Total price of the sale is drawn from the global state } this.props.cart.map((product) => { var item = {}; item.name = product.name; item.product_id = product._id; item.cartQuantity = product.cartQuantity; item.priceValue = product.price; props.items.push(item); }); var jsonProps = JSON.stringify(props); //converts properties into json before sending them to the server this.props.makeSale(jsonProps); } 

动作/ index.js

 export function makeSale(props) { var config = {headers: {'authorization' : localStorage.getItem('token')}}; var request = axios.post('/makeSale', props, config); //This will store the sale in the database and also return it return { type: MAKE_SALE, payload: request //Sends sale along to be used in sale_reducer.js }; } 

router.js

  //Adds a new sale to the database //Getting error "can't set headers after they are sent" app.post('/makeSale', function(req, res, next){ var sale = new Sale(); sale.owner = req.body.user_id; sale.total = req.body.total; req.body.items.map((item)=> { //pushs an item from the request object into the items array contained in the sale document sale.items.push({ item: item.product_id, itemName: item.name, cartQuantity: parseInt(item.cartQuantity), //adds cartQuantity to sale price: parseFloat(item.priceValue) }); Product.findById(item.product_id) .then((product) => { //finds the item to be sold in the database and updates its quantity field based on the quantity being sold product.quantity -= item.cartQuantity; //resets the product's cartQuantity to 1 product.cartQuantity = 1; product.save(function(err) { if (err) { return next(err); } else { return next(); // return res.status(200).json(product); } }); }, (error) => { return next(error); }); }); //gives the sale a date field equal to current date sale.date = new Date(); //saves and returns the sale sale.save(function(err) { if (err) { return next(err); } return res.status(200).json(sale); //Returns the sale so that it can be used in the sale_reducer.js }); }); 

这里是mongoose的销售模式 – > sale.js

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; var SalesSchema = new Schema({ owner: { type: Schema.Types.ObjectId, ref: 'User'}, total: { type: Number, default: 0}, items: [{ item: { type: Schema.Types.ObjectId, ref: 'Product'}, itemName: { type: String, default: "no name provided"}, cartQuantity: { type: Number, default: 1 }, price: { type: Number, default: 0 } }], date: Date }); module.exports = mongoose.model('Sale', SalesSchema); 

Product.findById是asynchronous的,最终会多次调用next() ,这很可能导致试图多次发送响应,这会导致错误。

通常(或者总是可能),您只需要针对每个中间件调用next()

尝试这个:

 "use strict"; app.post('/makeSale', function(req, res, next){ var sale = new Sale(); sale.owner = req.body.user_id; sale.total = req.body.total; return Promise.all(req.body.items.map((item) => { // pushs an item from the request object into the items array contained in the sale document sale.items.push({ item: item.product_id, itemName: item.name, cartQuantity: parseInt(item.cartQuantity, 10), // adds cartQuantity to sale price: parseFloat(item.priceValue) }); return Product.findById(item.product_id).then((product) => { //finds the item to be sold in the database and updates its quantity field based on the quantity being sold product.quantity -= item.cartQuantity; //resets the product's cartQuantity to 1 product.cartQuantity = 1; return product.save(); }); })) .then(() => { //gives the sale a date field equal to current date sale.date = new Date(); //saves and returns the sale return sale.save(); }) .then(() => { return res.status(200).json(sale); }) .catch(next); }); 

在您的路线中,您为每个保存的产品调用next() 。 你res.status(200).json(sale)

调用next()告诉Express你的路由处理器对处理请求不感兴趣,所以Express将它委托给下一个匹配的处理器(或者如果没有的话,则是一个通用的Not Found处理器)。 您不能再次调用next() ,或者自己发回回复,因为您已经告诉Express您不感兴趣。

你应该重写req.body.items.map(...)以便它根本不会调用next()

一个解决scheme是使用async.map() 。 然后你可以在最后的callback中调用next(error) (如果有的话) res.json()

我很less使用JS作为后端,但通常这意味着在您已经发送/发送HTTP正文后,您正在尝试设置HTTP标头。

基本上:只要确保你的头被发送之前,你打印什么,屏幕是什么错误的意思。