How can I continuously inform the user of progress from a Perl CGI script?

前端 未结 6 661
一整个雨季
一整个雨季 2021-01-13 12:04

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/ht         


        
相关标签:
6条回答
  • 2021-01-13 12:16

    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

    0 讨论(0)
  • 2021-01-13 12:17

    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.

    0 讨论(0)
  • 2021-01-13 12:25

    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).

    0 讨论(0)
  • 2021-01-13 12:26

    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.

    0 讨论(0)
  • 2021-01-13 12:33

    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)

    0 讨论(0)
  • 2021-01-13 12:42

    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.

    0 讨论(0)
提交回复
热议问题