【问题标题】:Can`t set headers after they are sent发送后无法设置标题
【发布时间】:2017-09-23 12:16:53
【问题描述】:

我正在尝试在我的代码中查找错误,但其他主题中没有任何内容适合。

有 app.js 代码,其中包含来自 Express 模块的get 方法:

app.get('/notes', notesController.all);

有notesController.js代码,导出到app.jscreate方法:

exports.all = function (req, res) {
    Notes.all(function(err, docs){
        if(err){
            console.log(err);
            return res.sendStatus(500);
        }
        res.send(docs);
    })
};

model这个代码:

exports.all = function (cb) {
    db.get().collection('notes').find().toArray(function (err, docs) {
        cb(err,docs);
    })
};

应用程序因此错误而崩溃:

process.nextTick(function() { throw err; });
                              ^

错误:发送后无法设置标头。 在 ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11) 在 ServerResponse.header (O:\OGPI6\node_modules\express\lib\response.js:725:10) 在 ServerResponse.json (O:\OGPI6\node_modules\express\lib\response.js:253:10) 在 ServerResponse.send (O:\OGPI6\node_modules\express\lib\response.js:158:21) 在 O:\OGPI6\controllers\notes.js:9:13 在 O:\OGPI6\models\notes.js:6:9 在 handleCallback (O:\OGPI6\node_modules\mongodb\lib\utils.js:120:56) 在 O:\OGPI6\node_modules\mongodb\lib\cursor.js:860:16 在 handleCallback (O:\OGPI6\node_modules\mongodb-core\lib\cursor.js:171:5) 在 setCursorDeadAndNotified (O:\OGPI6\node_modules\mongodb-core\lib\cursor.js:505:3)

在我看来,回调函数中只有“控制器”的错误:

if(err){
            console.log(err);
            return res.sendStatus(500);
        }
        res.send(docs);

但我认为当发生错误时它必须终止函数并返回sendStatus(500),但在控制台中记录错误后它会尝试返回res.send(docs),然后应用程序崩溃,因为它正在发送第二个标头。它看起来不错,但不起作用。谁能指出我失败的方式?

【问题讨论】:

  • 您是否认为您的exports.all 方法可能会多次触发回调。您是否尝试在回调的开头添加console.log
  • 我同意@BenjiLees,看起来回调被调用了两次。

标签: javascript node.js mongodb express


【解决方案1】:

使用中间件中的“next”参数,让express知道这个中间件的目的已经完成,不需要再执行代码了。

exports.all = function (req, res, next) {
    Notes.all(function(err, docs){
        if(err){
            console.log(err);
            res.sendStatus(500);
            return next();
        }
        res.send(docs);
    })
};

返回后执行代码可能是由于异步性质。

你也可以使用 else 块。

exports.all = function (req, res, next) {
        Notes.all(function(err, docs){
            if(err){
                console.log(err);
                res.sendStatus(500);

            }
            else res.send(docs);
        })
    };

【讨论】:

  • 发回响应调用next都不是一个好主意,因为next可能会使Express将控制权传递给另一个请求处理程序(或最终的“不找到的”处理程序)也可能发回响应。
【解决方案2】:

把代码改成

if(err){
  console.log(err);
  return res.status(500).send(err);
}
res.send(docs);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多