Nodejs:在第一个连接回调中连接和"writeHead"



我总是收到错误"错误:发送后无法设置标头。"时调用"res.writeHead(...)"在连接的第一个回调中:

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:UsersdrtSkyDriveProgrammierungnodejssilkveilnode_modulesconnectlibpatch.js:63:22)
    at next (C:UsersdrtSkyDriveProgrammierungnodejssilkveilnode_modulesconnectlibproto.js:156:13)
    at Object.handle (C:UsersdrtSkyDriveProgrammierungnodejssilkveilconnectSampleApp.js:13:3)
    at next (C:UsersdrtSkyDriveProgrammierungnodejssilkveilnode_modulesconnectlibproto.js:193:15)
    at Function.app.handle (C:UsersdrtSkyDriveProgrammierungnodejssilkveilnode_modulesconnectlibproto.js:201:3)
    at Server.app (C:UsersdrtSkyDriveProgrammierungnodejssilkveilnode_modulesconnectlibconnect.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();
    });

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

检查另一个问题。基本上在调用res.writeHead后,无法再修改标头,而next方法将尝试修改会导致异常的标头。

所以你可以在第一个连接回调中修改标头,但不允许写入 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.end();

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

最新更新