【问题标题】:Node.js Can't set headers after they are sent, res.json never called twiceNode.js 发送后无法设置标头,res.json 从未调用过两次
【发布时间】:2017-03-31 07:32:14
【问题描述】:

我正在为一个经济系从事大学项目。我有很多路线可以正常工作,但只有这一条给我带来了很大的问题。

每当这条路线完成并发送响应时,我都会收到以下错误:

Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:719:10)
at ServerResponse.send (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:164:12)
at ServerResponse.json (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:250:15)
at /Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/controllers/application.js:171:56
at Query._callback (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/models/application.js:141:25)
at Query.Sequence.end (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Sequence.js:85:24)
at Query._handleFinalResultPacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Query.js:144:8)
at Query.OkPacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Query.js:78:10)
at Protocol._parsePacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/Protocol.js:280:23)

以下是该路由调用的函数:

registerFactory: function (req, res ) {
        var userDetails = req.user;
        var requestData = req.body;
        var hscode = "NULL";
        var applicationID = "FR";
        var applicationType = "Factory";
        var factoryId = "";
        if (userDetails.usergroup == "Client") {
            var d = new Date();
            var year = d.getFullYear();
            applicationID = applicationID + year;
            var dnum = 5;
            var num = 0;
            applicationModel.getLastAppID(applicationType, function (err, results) {
                if (err) {
                    return res.json({success: false, message: 'Database Error. '});
                }else{
                    num = results[0].LastID;
                    console.log(num);
                    dnum = dnum - num.toString().length;
                    while (dnum != 0) {
                        applicationID = applicationID + "0";
                        dnum = dnum - 1;
                    }
                    applicationID = applicationID + num;
                    num = num + 1;
                    applicationModel.updateLastAppID(num, applicationType, function (err) {
                        if (err) {
                            return res.json({success: false, message: 'Database Error. '});
                        }else{
                            factoryController.registerFactory(userDetails,requestData, function (err,FID) {
                                if (err) {
                                    return res.json({success: false, message: 'Database Error. '});
                                }else{
                                    factoryId =  FID;
                                    applicationModel.createFactoryRegApplication(userDetails, requestData, applicationType, applicationID,hscode, function (err) {
                                        if (err) {
                                            return res.json({success: false, message: 'Database Error. '});
                                        } else {
                                            res.json({
                                                success: true,
                                                message: 'Application Created',
                                                data: {RequestID: applicationID,
                                                    FactoryID : factoryId
                                                }
                                            });
                                        }
                                    });
                                }
                            });

                        }
                    });
                }
            });
        } else {
            return res.json({success: false, message: 'unauthorized Access'});
        }
    }

我不知道为什么会发生这种情况,即使 res.json 从未被调用两次。

【问题讨论】:

  • at /Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/controllers/application.js:171:56 你的代码是哪一行?
  • 这个 :res.json({ success: true, message: 'Application Created', data: {RequestID: applicationID, FactoryID : factoryId }
  • 你在这段代码后面会调用res.end()吗?
  • 不,我没有调用 res.end()

标签: javascript json node.js express


【解决方案1】:

这样的代码极难维护:

http://icompile.eladkarako.com/wp-content/uploads/2016/01/icompile.eladkarako.com_callback_hell.gif

它甚至不适合这里的屏幕,所以我很难阅读它。我可以给你一些关于如何重构它以使其易于管理的一般性建议。希望这将帮助您解决此问题以及将来的类似问题。

首先,获取每个匿名函数并将其更改为命名函数。所以,当你有:

applicationModel.updateLastAppID(num, applicationType, function (err) {
  // ...
});

改成:

applicationModel.updateLastAppID(num, applicationType, updatedLastAppID);

function updatedLastAppID(err) {
  // ...
}

使用您拥有的每个 function 进行操作。仅此一项就可能会向您展示您的问题,因为您将拥有一个易于阅读和理解的漂亮的自记录代码,因为:

  • 函数将被命名,错误也将更容易阅读
  • 到目前为止,任何内容都不会缩进到屏幕之外
  • 您一次只能查看一个功能

例如:

                applicationModel.updateLastAppID(num, applicationType, function (err) {
                    if (err) {
                        return res.json({success: false, message: 'Database Error. '});
                    }else{
                        factoryController.registerFactory(userDetails,requestData, function (err,FID) {
                            if (err) {
                                return res.json({success: false, message: 'Database Error. '});
                            }else{
                                factoryId =  FID;
                                applicationModel.createFactoryRegApplication(userDetails, requestData, applicationType, applicationID,hscode, function (err) {
                                    if (err) {
                                        return res.json({success: false, message: 'Database Error. '});
                                    } else {
                                        res.json({
                                            success: true,
                                            message: 'Application Created',
                                            data: {RequestID: applicationID,
                                                FactoryID : factoryId
                                            }
                                        });
                                    }
                                });
                            }
                        });
                    }
                });

会变成这样:

applicationModel.updateLastAppID(num, applicationType, updatedID);

function updatedID(err) {
  if (err) {
    return res.json({success: false, message: 'Database Error. '});
  } else {
    factoryController.registerFactory(userDetails, requestData, factoryRegistered);
  }
}
// etc.

这是第一步,但如果没有它,您将很难确保一切正常。

这并不难,你可以一步一步自己做。如果您没有立即看到问题,那么您可以发布另一个问题,但使用可读的代码您将更有可能获得答案。

【讨论】:

    猜你喜欢
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 2018-03-13
    • 1970-01-01
    • 2018-05-05
    • 2016-12-19
    • 1970-01-01
    相关资源
    最近更新 更多