Подтвердить что ты не робот

Как я могу выводить данные до того, как закончу ответ?

Вот мой фрагмент, который я тестировал в Chrome 11, и Firefox 4:

var http = require('http');

http.createServer(function(request, response){
   // Write Headers
   response.writeHead(200);

   // Write Hello World!
   response.write("Hello World!");

   // End Response after 5 seconds
   setTimeout(function(){ 
        response.end(); 
   }, 5000);

}).listen(8000);

Как вы можете видеть, я отключил response.end(), поэтому могу проверить, выводится ли response.write до response.end. По моему опыту, хотя это не так.

Есть ли способ вывода данных перед завершением ответа, что-то вроде отправки данных в пакетах?

4b9b3361

Ответ 1

Если вы измените тип контента на text/plain - например:

// Write Headers
response.writeHead(200, {'Content-Type': 'text/plain'});

то firefox немедленно покажет содержимое. Хром по-прежнему кажется буферным (если вы пишете больше контента, хром покажет его сразу).

Ответ 2

Фактически вы можете сделать это без установки Content-Type: text/plain и по-прежнему использовать text/html как Content-Type, но вам нужно сказать браузеру, что он ожидает куски данных.

Это можно сделать так:

var http = require('http');

http.createServer(function(request, response) {

    response.setHeader('Connection', 'Transfer-Encoding');
    response.setHeader('Content-Type', 'text/html; charset=utf-8');
    response.setHeader('Transfer-Encoding', 'chunked');

    response.write('hello');

    setTimeout(function() {
        response.write(' world!');
        response.end();
    }, 10000);

}).listen(8888);


Вы должны знать, что до тех пор, пока response.end() не будет вызван, запрос все еще происходит и блокирует другие запросы на ваш сервер nodejs.
Вы можете легко проверить это, открыв вызов этой страницы (localhost: 8888) на двух разных вкладках. Один из них будет ждать 10 секунд, а другой получит только начало ответа после окончания первого ответа (что означает, что вы будете ждать 10 секунд для начала ответа и еще 10 секунд до конца ответа, используя этот код).

Возможно, вы тоже можете преодолеть это препятствие, запустив несколько процессов nodejs и балансировку нагрузки между ними, но затем это начинает усложняться и является потоком, который следует принимать иначе, где...:)

Ответ 3

Если вы хотите вывести chunked plain text в Chrome - так же, как по умолчанию Firefox, вам нужно использовать заголовок 'X-Content-Type-Options': 'nosniff'. См. Что такое "X-Content-Type-Options = nosniff" ?

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {
        'Content-Type': 'text/plain; charset=utf-8',
        'Transfer-Encoding': 'chunked',
        'X-Content-Type-Options': 'nosniff'});
    res.write('Beginning\n');
    var count = 10;
    var io = setInterval(function() {
        res.write('Doing ' + count.toString() + '\n');
        count--;
        if (count === 0) {
            res.end('Finished\n');
            clearInterval(io);
        }
    }, 1000);
}).listen(8888);

Эта опция не нужна, если ваш результат text/html.

Решение, найденное из этого дефекта Chrome: Передача-кодировка помечена не поддерживается по тексту/plain

Ответ 4

Вот основные моменты, которые необходимо учитывать:

  • укажите кодировку
  • каждый "кусок" будет выводиться браузером (по крайней мере, что я заметил в Chrome) через новую строку (<br>, если charset - text/html)

Так же:

res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.write('a<br>');
setTimeout(function() {
  res.write('b<br>');
  setTimeout(function() {
    res.write('c');
    res.end();
  }, 2000);
}, 2000);