如何从Perl CGI脚本持续通知用户进度?

如何从Perl CGI脚本持续通知用户进度?,perl,apache,cgi,Perl,Apache,Cgi,我的Apache服务器的cgi bin文件夹中有一个Perl脚本: #!/usr/bin/perl use strict; use warnings; $| = 1; print "Content-type: text/html\r\n\r\n"; print "Hello there!<br />\nJust testing .<br />\n"; my $top = 5; foreach (1..$top) { print "i = $_<br

我的Apache服务器的cgi bin文件夹中有一个Perl脚本:

#!/usr/bin/perl 
use strict;
use warnings;

$| = 1;

print "Content-type: text/html\r\n\r\n";
print "Hello there!<br />\nJust testing .<br />\n";

my $top = 5;
foreach (1..$top) {
    print "i = $_<br />\n";
    sleep 1;
}
#/usr/bin/perl
严格使用;
使用警告;
$| = 1;
打印“内容类型:text/html\r\n\r\n”;
打印“你好!
\n正在测试。
\n”; 我的$top=5; foreach(1..$top){ 打印“i=$\ubr/>\n”; 睡眠1; }
我想在这里实现的是逐步更新网页,向用户显示更新状态。然而,我实际上得到的是一次完整的输出,经过5秒的延迟

有没有什么方法可以让我编写一个脚本来不断地通知用户它的进度?我有一个需要很长时间才能完成的脚本,我希望能够实时看到它的进度,而不是整个脚本才能完成


我还尝试将自动刷新模式设置为off($|=0),但即使这样也没有任何作用。

您想要实现的目标是可能的——浏览器通常会呈现到目前为止收到的内容,即使它不是完整的文档,只要有足够的标记能够呈现任何内容。但是,我想知道为什么您对某些输出使用
\r\n
,而对其他输出使用
\n
——您应该始终保持一致并使用
\n
。此外,您指定的内容类型为text/html,但在内容之前不提供任何html标题(


但是,“现代”的方法是立即返回页面输出,但将稍后要更新的部分保留为空的
元素。然后,您可以使用javascript(通过AJAX请求)更新该元素的内容。

当您将内容类型设置为text/plain时,它是否达到了预期效果?可能是浏览器中的HTML解析导致了输出延迟,因为您实际上没有输出有效的HTML?(无或标记)

假设您使用的是高于1.3的Apache版本,这应该可以工作。否则,您必须将脚本制作成NPH(无解析头)CGI,这意味着它的文件名应该以
NPH-
作为前缀,并且它应该输出完整的HTTP头,例如

HTTP/1.1 200 OK\n
Content-type: text/html\n\n

有关更多信息,请参见(有点旧的)Randal Schwartz展示了一种更好的方法

这就是说,在内容类型上撒谎也无济于事。下面的脚本正是您希望它在使用Apache 2.2的Windows XP上执行的操作(即最后一行输出需要10秒钟):


现在,如果您正在发送HTML,您无法避免这样一个事实,即大多数浏览器都会等到他们认为页面的内容足够时才开始呈现。

要查看脚本是否正常工作,请尝试使用命令行工具以避免与浏览器混淆<例如,code>curl,一旦接收到数据就会输出


如果你所做的是为了一个重要的目的,我不会使用你目前的方法。如果脚本需要很长时间才能运行,请将其转移到后台()并使用进度更新文件或数据库。然后可以使用自动刷新(JavaScript或元刷新)iFrame来显示进度。您也可以使用AJAX,但这要复杂一点。

它通过禁用特定虚拟主机的Deflate模块对我有效

SetEnv no-gzip 1

我想您也可以使用.htaccess文件获得相同的结果。

您使用的是哪个版本的Apache?高于1.3?已尝试将输出类型设置为文本/普通,但仍然无效。。。输出仍然延迟。您使用的浏览器是什么?如果浏览器进行内容嗅探,如果您仍然发送html,它将忽略您的内容类型。
SetEnv no-gzip 1