【问题标题】:Nodejs: Connect and "writeHead" in first connect-callbackNodejs:在第一个连接回调中连接和“writeHead”
【发布时间】:2013-11-14 23:24:44
【问题描述】:

当在第一个 connect 回调中调用“res.writeHead(...)”时,我总是收到错误“Error: Can't set headers after they are sent.”:

var http = require('http');
var connect = require('connect');

var simpleApp = connect();

simpleApp
    .use(function(req, res, next){

        res.writeHead(200, { 'content-type': 'text/html' });
        res.write('response powered by SIMPLE connect-object as middelware');

        console.log('Pre');
        next();
        console.log('Post');
    })
    .use(function(req, res, next){
        console.log('I am the header guy!');
        next();
    })
    .use('/admin', function(req, res, next){
        console.log('someone entered the admin area....');
        next();
    })
    .use(function(req, res){
        console.log('reached the tail of the "chain of responsibility!!!');
        res.end();
    });

http.createServer(simpleApp).listen(process.env.PORT || 3000);

console.log('Running on port "' + (process.env.PORT || 3000) + '"');

// just a save-guard to stop the process after some time...
setTimeout(function(){
    process.exit(0);
}, 20000);

这是错误信息:

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
    at ServerResponse.res.setHeader (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\patch.js:63:22)
    at next (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\proto.js:156:13)
    at Object.handle (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\connectSampleApp.js:13:3)
    at next (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\proto.js:193:15)
    at Function.app.handle (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\proto.js:201:3)
    at Server.app (C:\Users\drt\SkyDrive\Programmierung\nodejs\silkveil\node_modules\connect\lib\connect.js:65:37)
    at Server.EventEmitter.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2108:12)

当我将“writeHead”代码移动到最后一个回调中时,一切都很好:

.use(function(req, res){
        console.log('reached the tail of the "chain of responsibility!!!');
        res.writeHead(200, { 'content-type': 'text/html' });
        res.write('response powered by SIMPLE connect-object as middelware');
        res.end();
    });

所以我的问题是:是否只允许在使用连接时在最后一个回调中使用 writeHead /write?

【问题讨论】:

    标签: node.js connect


    【解决方案1】:

    检查另一个问题。 res.writeHead 基本上在res.writeHead被调用后,header就不能再修改了,而next方法会尝试修改header导致异常。

    所以你可以在第一个connect回调中修改header,但是你不能写body(res.write)。以下代码应该可以正常工作。简而言之,您可以修改标题但不能刷新它们。

    var http = require('http');
    var connect = require('connect');
    
    var simpleApp = connect();
    
    simpleApp
        .use(function(req, res, next){
            res.statusCode = 200;
            res.setHeader( 'content-type', 'text/html' );
    
            console.log('Pre');
            next();
            console.log('Post');
        })
        .use(function(req, res, next){
            console.log('I am the header guy!');
            next();
        })
        .use('/admin', function(req, res, next){
            console.log('someone entered the admin area....');
            next();
        })
        .use(function(req, res){
            res.write('response powered by SIMPLE connect-object as middelware');
            console.log('reached the tail of the "chain of responsibility!!!');
            res.end();
        });
    
    http.createServer(simpleApp).listen(process.env.PORT || 3000);
    
    console.log('Running on port "' + (process.env.PORT || 3000) + '"');
    
    // just a save-guard to stop the process after some time...
    setTimeout(function(){
        process.exit(0);
    }, 20000);
    

    【讨论】:

    • 好的,所以只有“允许”在最后一个回调中调用“res.write”!?因为我可以使用“res.setHeader('content-type', 'text/html');”在第一个回调中,它正在工作。
    • 对,您必须在最后一个回调之前将响应留在 Head 部分。
    • 感谢您的回答
    【解决方案2】:

    您在第一部分代码中忘记了这一行:

    res.end();
    

    如果这不起作用,这里有 TJ Holowaychuk 的评论: https://github.com/senchalabs/connect/issues/683#issuecomment-10018892

    【讨论】:

    • "res.end()" 在最后一个连接回调中被调用。我的想法是我在不同的回调中写入响应,然后在最后一个回调中结束响应,我不理解您链接中的评论......为什么使用“writeHead”不是一个好主意?我对 node.js 很陌生,所以请耐心等待
    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 2021-04-27
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多