1

在 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 秒接收一次输出。

无论如何告诉现代浏览器(可能通过标题?)以旧方式行事并在行到达时显示?

4

1 回答 1

1

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

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

使用“传输编码:分块”,浏览器开始渲染之前必须发送多少数据?

因此生成的代码将类似于:

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

于 2017-10-24T23:45:57.123 回答