2013-11-14 38 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