2013-11-14 2 views
1

Я получаю всегда ошибку «Ошибка: не удается установить заголовки после их отправки.» при вызове «res.writeHead (...)» в очень первый обратный вызов подключения:Nodejs: Connect и «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» -код в самом последние обратном вызове все в порядке:

.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 в самом последнем обратном вызове при использовании соединения?

ответ

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

«Res.end()» вызывается в самом последнем соединении-обратном вызове. Моя идея заключается в том, что я пишу в ответ в differnt callbacks, а затем заканчиваю ответ в самом последнем обратном вызове, и я не понимаю комментарий в вашей ссылке ... почему не рекомендуется использовать «writeHead»? Я совершенно новичок в node.js, так что медведь со мной – thuld

Смежные вопросы