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

发布于 2024-08-08 21:58:43 字数 504 浏览 4 评论 0原文

我的 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;
}

我想在这里实现的是逐步更新网页以向用户显示更新的状态。然而,我实际上得到的是在延迟 5 秒后立即得到的整个输出。

有什么方法可以编写一个能够持续通知用户其进度的脚本吗?我有一个需要很长时间才能完成的脚本,我希望能够实时看到其进度,而不是整个脚本才能完成。

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

I have this Perl script sitting in the cgi-bin folder of my Apache server:

#!/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;
}

What I want to achieve here is a gradual update of the web page to show the user an updated status. However, what I'm actually getting is the entire output at once, after a delay of 5 secs.

Is there any way I can write a script that is able to continuously inform the user of its progress? I have a script that takes a long time to finish and I would like to be able to see its progress in real time rather than the whole script to finish.

I have also tried to set autoflush mode to off ($| = 0), but even that doesn't do any thing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

已下线请稍等 2024-08-15 21:58:43

Randal Schwartz 在通过 CGI 观察长进程中展示了一种更好的方法。

也就是说,在内容类型上撒谎是没有帮助的。下面的脚本完全符合您在使用 Apache 2.2 的 Windows XP 上执行的操作(因为最后一行输出需要 10 秒才能出现):

#!/usr/bin/perl

use strict;
use warnings;

use CGI qw(:cgi);

print header('text/plain');

$| = 1;

print "Job started\n";

for ( 1 .. 10 ) {
    print "$_\n";
    sleep 1;
}

现在,如果您要发送 HTML,则无法避免以下事实:大多数浏览器会等到他们认为页面足够了才开始渲染。

Randal Schwartz shows a better way in Watching long processes through CGI.

That said, lying about the content type will not help. The following script does exactly what you seem to want it to do on Windows XP with Apache 2.2 (in that it takes ten seconds for the last line of output to appear):

#!/usr/bin/perl

use strict;
use warnings;

use CGI qw(:cgi);

print header('text/plain');

$| = 1;

print "Job started\n";

for ( 1 .. 10 ) {
    print "$_\n";
    sleep 1;
}

Now, if you are sending HTML, you cannot avoid the fact that most browsers will wait until they what they believe is enough of the page to begin rendering.

川水往事 2024-08-15 21:58:43

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

但是,执行此操作的“现代”方法是立即返回页面输出,但将稍后要更新的部分保留为空

元素。然后您可以使用 javascript 更新该元素的内容(通过 AJAX 请求)。

What you are wanting to achieve is possible -- browsers generally render what it has received so far, even if it is not the complete document, provided there is sufficient markup to be able to render anything at all. I'm wondering however why you use \r\n for some output and just \n for others -- you should be consistent and use \n throughout. Additionally, you are specifying a content type of text/html, but not providing any html headers (<html><title></title><body>) before your content.

However, the "modern" way to do this is to return the page output immediately, but leave the part you want to update later as an empty <div> element. Then you can update the content of that element with javascript (via an AJAX request).

蓬勃野心 2024-08-15 21:58:43

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

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

请参阅(有点旧)Apache 常见问题解答了解更多信息

Assuming you are using a version of Apache newer than 1.3, this should work. otherwise, You'll have to make your script into an NPH (No Parsed Headers) CGI, meaning its filename should be prefixed with nph- and it should output complete HTTP headers, eg.

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

see the (somewhat old)Apache FAQ for more info

梦初启 2024-08-15 21:58:43

要查看您的脚本是否正常工作,请尝试使用命令行工具以避免与浏览器产生任何混淆。例如curl,一旦收到数据就会输出。

不过,如果您所做的事情是出于重要目的,那么我不会使用您当前的方法。如果脚本需要很长时间才能运行,请将其分叉到后台 (信息)并按进度更新文件或数据库。然后,您可以使用自动刷新(JavaScript 或 META-REFRESH)iFrame 来显示进度。您还可以使用 AJAX,但这有点复杂。

To see if your script is working, try using a command line tool to avoid any confusion with your browser. curl, for example, will output as soon as it receives data.

If what you are doing is for an important purpose, I wouldn't use your current approach, though. If the script takes a long time to run, fork it off into the background (info here) and update a file or database with progress. You can then use an auto-refreshing (JavaScript or META-REFRESH) iFrame to display the progress. You could also use AJAX, but that is a bit more involved.

如何视而不见 2024-08-15 21:58:43

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

SetEnv no-gzip 1

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

It worked for me by disabling the Deflate module for that particular virtual host.

SetEnv no-gzip 1

I guess you could achieve the same result using a .htaccess file too.

裸钻 2024-08-15 21:58:43

当您将内容类型设置为文本/纯文本时,它是否符合您的预期?也许浏览器中的 HTML 解析导致了输出延迟,因为您实际上并未输出有效的 HTML? (没有 或 标签)

Does it do what you expect when you set the content-type to text/plain? Perhaps the HTML parsing in your browser is causing the delay in the output, since you're not actually outputting valid HTML? (no <html> or <body> tags)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文