2009-10-29 15 views
5

tengo este script Perl sentado en la carpeta cgi-bin de mi servidor Apache:¿Cómo puedo informar continuamente al usuario sobre el progreso de una secuencia de comandos Perl CGI?

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

Lo que quiero lograr aquí es una actualización gradual de la página web para mostrar al usuario un estado actualizado. Sin embargo, lo que realmente obtengo es todo el resultado a la vez, después de un retraso de 5 segundos.

¿Hay alguna manera de que pueda escribir un script que es capaz de mantener informados a los usuarios de su progreso? Tengo un script que tarda mucho tiempo en terminar y me gustaría poder ver su progreso en tiempo real en lugar de todo el script para terminar.

También han tratado de establecer el modo de descarga automática de apagado ($ | = 0), pero incluso eso no hace nada.

+0

¿En qué versión de Apache estás? más nuevo que 1.3? – Hasturkun

Respuesta

5

Randal Schwartz muestra una mejor manera en Watching long processes through CGI.

Dicho esto, mentir sobre el tipo de contenido no ayudará. El siguiente script hace exactamente lo que parece que quiere que haga en Windows XP con Apache 2.2 (en el que se tarda diez segundos en la última línea de salida a aparecer):

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

Ahora, si van a enviar HTML , no se puede evitar el hecho de que la mayoría de los navegadores esperarán hasta que crean que es suficiente para comenzar a renderizar.

4

Lo que quiere lograr es posible: los navegadores generalmente procesan lo que han recibido hasta el momento, incluso si no es el documento completo, siempre que haya suficiente marcado para poder representar cualquier cosa. Sin embargo, me pregunto por qué usa \r\n para obtener resultados y solo \n para otros; debe ser coherente y usar \n en todas partes. Además, está especificando un tipo de contenido de texto/html, pero no proporciona ningún encabezado html (<html><title></title><body>) antes de su contenido.

Sin embargo, la forma "moderna" de hacerlo es devolver la salida de la página inmediatamente, pero deje la parte que desea actualizar más tarde como un elemento <div> vacío. Luego puede actualizar el contenido de ese elemento con javascript (a través de una solicitud AJAX).

+0

intentado dar salida a una página HTML válida, sigue teniendo la misma respuesta ... – Jibran

0

¿Hace lo que se puede esperar cuando se establece el tipo de contenido de text/plain? Tal vez el análisis de HTML en su navegador está causando el retraso en la salida, ya que en realidad no está produciendo HTML válido. (Sin <html> o <cuerpo> etiquetas)

+0

intenté configurar el tipo de salida como texto/normal, todavía nada ... la salida todavía está retrasada. – Jibran

+0

¿Qué navegador estás usando? Si el navegador inhala contenido, simplemente ignorará su tipo de contenido si envía html de todos modos. – innaM

2

Suponiendo que está utilizando una versión de Apache más nuevo que 1,3, esto debería funcionar. de lo contrario, tendrá que hacer que su script se convierta en un CGI de NPH (No Parsed Headers), lo que significa que su nombre de archivo debe tener el prefijo nph- y debe mostrar encabezados completos de HTTP, por ejemplo.

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

ver el (un poco viejo) Apache FAQ para obtener más información

2

para ver si su secuencia de comandos funciona, pruebe a utilizar una herramienta de línea de comandos para evitar cualquier confusión con su navegador. curl, por ejemplo, saldrá tan pronto como reciba datos.

Si lo que está haciendo es para un propósito importante, yo no usaría su enfoque actual, sin embargo.Si el script tarda mucho tiempo en ejecutarse, bótelo en segundo plano (info here) y actualice un archivo o base de datos con el progreso. A continuación, puede utilizar un iFrame de renovación automática (JavaScript o META-REFRESH) para mostrar el progreso. También puedes usar AJAX, pero eso es un poco más complicado.

0

Me funcionó al deshabilitar el módulo Deflate para ese host virtual en particular.

SetEnv no-gzip 1 

Supongo que también puede obtener el mismo resultado utilizando un archivo .htaccess.

Cuestiones relacionadas