Wie erstelle ich eine 'Bitte Warten'-Seite?
Inhalt:
Problem
Ein CGI-Skript führt einen langwierigen Prozess aus, aber der Benutzer soll
solange eine 'Bitte Warten'-Seite sehen.
Lösung
Man forkt den Prozess und macht einen Redirect auf ein Skript, dass prüft, ob
der Prozess zu ende ist. Wenn ja, zeigt es das Ergebnis an, wenn nicht, macht
es einen meta-refresh auf sich selbst.
Folgendes Skript veranschaulicht dies mit einer etwas sinnlosen Funktion, die aber
das Prinzip zeigt.
#!/usr/bin/perl
# background.pl
# Aufruf: http://server/background.pl?w=create;count=5
use strict;
use warnings;
use CGI;
use Fcntl qw(:flock);
my $cgi = CGI->new;
my $url = "http://server/background.pl";
my $w = $cgi->param('w') || 'show';
if ($w eq 'show') {
show($cgi);
}
elsif ($w eq 'create') {
create($cgi);
}
sub create {
my ($cgi) = @_;
my $val = $cgi->param('count') || 5;
if ($val =~ tr/0-9//c or $val > 10) {
$val = 5;
}
my $id = time() . $$;
my $filename = "background.id$id";
$SIG{CHLD} = 'IGNORE';
if (my $pid = fork) {
# parent
print $cgi->redirect("/background.pl?w=show;id=$id");
close STDOUT;
close STDERR;
close STDIN;
exit;
}
else {
open my $fh, ">", $filename or die $!;
flock $fh, LOCK_EX;
close STDOUT;
close STDERR;
close STDIN;
for my $i (1 .. $val) {
print $fh "$i\n";
sleep 2;
}
close $fh;
exit;
}
}
sub show {
my ($cgi) = @_;
my $id = $cgi->param('id') || '';
$id =~ tr/0-9//cd;
print $cgi->header;
if (length $id > 20) {
print $cgi->start_html;
print "too long";
}
else {
my $filename = "background.id$id";
my $meta = $cgi->start_html(
my $meta_refresh =
-head => $cgi->meta(
{
-http_equiv => 'refresh',
-content => "2; $url?w=show;id=$id",
}
));
if (open my $fh, "<", $filename) {
my $lock = flock $fh, LOCK_EX|LOCK_NB;
if ($lock) {
# success, got lock
my $output = do { local $/; <$fh> };
print "Result: $output";
}
else {
print $meta;
print "Not finished";
}
close $fh;
}
else {
print $meta;
print "File not yet created";
}
}
print $cgi->end_html;
}
Ergänzungen, Kommentare
Kommentare werden am besten in folgender Form vorgenommen, damit
sie im Inhaltsverzeichnis angezeigt werden (natürlich ohne das <verbatim>):
---+++ Main.??? - 14 Jul 2003 - Betreff