2013-11-14 32 views
1

我总是收到错误“错误:发送后无法设置标头。”在调用“res.writeHead(...)”时的连接的第一个回调:Nodejs:在第一个连接回调中连接和“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:\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” -code到最后回调一切都很好:

.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?

回答

2

检查的其他问题。 res.writeHead 基本上在调用res.writeHead之后,不能再修改标头,而next方法会尝试修改会导致异常的标头。

因此,您可以在第一次连接回调中修改标头,但不允许写入正文(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); 
+0

好的,所以在最后一次回调中只能“允许”调用“res.write”!因为我能够使用“res.setHeader('content-type','text/html');”在第一个回调中,它正在工作。 – thuld

+0

对,您必须在最后一次回拨之前将回复留在头部。 – Changgeng

+0

感谢您的回答 – thuld

0

你忘了这条线在你的代码的第一部分:

res.end(); 

如果不工作有来自TJ Holowaychuk这里评论: https://github.com/senchalabs/connect/issues/683#issuecomment-10018892

+0

在最后一次connect-callback中调用了“res.end()”。我的想法是,我写在不同的回调响应,然后在最后一次回调结束响应,我不明白你的链接中的评论......为什么使用“writeHead”不是一个好主意?我对node.js非常陌生,所以忍耐着我 – thuld