如何告诉现代浏览器在行到达时显示行

How to tell modern browsers to display lines as they arrive

在 Web 浏览器和服务器的早期,可以创建将数据发送到浏览器并且浏览器会在数据到达时显示的脚本。

例如传统的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 秒接收一次输出。

有没有办法告诉现代浏览器(也许通过 headers?)以旧方式运行并在到达时显示该行?

事实证明分块模式有效...但您需要先发送一堆数据,然后浏览器开始流式传输。

这描述了pre-chunk数据,通过测试确定:

Using "transfer-encoding: chunked", how much data must be sent before browsers start rendering it?

因此生成的代码类似于:

#!/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 用户帮助我解决这个问题)