Как заставить современные браузеры отображать строки по мере их поступления

В первые дни веб-браузеров и серверов было возможно создавать сценарии, которые отправляли бы данные в браузер, и браузер отображал их по мере их поступления.

Например, традиционный тестовый скрипт NPH:

#!/usr/local/bin/perl

$server_protocol = $ENV{'SERVER_PROTOCOL'};
$server_software = $ENV{'SERVER_SOFTWARE'};
$|=1;

print "$server_protocol 200 OK", "\n";
print "Server: $server_software", "\n";
print "Content-type: text/plain", "\n\n";

print "OK, Here I go. I am going to count from 1 to 5 !", "\n";

for ($loop=1; $loop <= 5; $loop++) {
    print $loop, "\n";
    sleep (2);
}

print "All Done!", "\n";

exit (0);

В старые времена Netscape браузер отображал 1, 2, 3, 4, 5, когда они появлялись с 2 секундами между ними.

В современном браузере, таком как Chrome, вы ничего не видите, пока скрипт не завершится и все 5 строк будут отображаться за один раз.

Я вижу, что скрипт работает так, как ожидал telnetвход на сервер и запуск руководства GET команда; вывод принимается каждые 2 секунды.

Есть ли какой-либо способ сказать современным браузерам (возможно, через заголовки?) Действовать по-старому и отображать строку по мере ее поступления?

1 ответ

Решение

Оказывается, работает чанкованный режим... но вам нужно сначала отправить кучу данных, прежде чем браузер начнет потоковую передачу.

Это описывает данные предварительной порции, определенные посредством тестирования:

Используя "Transfer-Encoding: Chunked", сколько данных должно быть отправлено, прежде чем браузеры начнут отображать его?

Таким образом, полученный код будет выглядеть примерно так:

#!/usr/local/bin/perl

$server_protocol = $ENV{'SERVER_PROTOCOL'};
$server_software = $ENV{'SERVER_SOFTWARE'};

$|=1;

print "$server_protocol 200 OK", "\n";
print "Server: $server_software", "\n";
print "Transfer-Encoding: chunked", "\n";
print "Content-type: text/plain", "\n\n";

sub chunk {
    my ($chunk)=@_;
    printf("%x\n%s\n", length($chunk), $chunk);  
}

# Send 1K of spaces to convince browsers to display data as it comes
chunk(" " x 1024);

chunk("OK, Here I go. I am going to count from 1 to 5 !\r\n");

for ($loop=1; $loop <= 5; $loop++) {
    chunk($loop . "\r\n");
    sleep (2);
}

chunk("All Done!\r\n");

# We need this to tell the client chunking has ended
chunk("");

(Спасибо не-SO пользователю за помощь в этом)

Другие вопросы по тегам