代码之家  ›  专栏  ›  技术社区  ›  Kurt W. Leucht

如何向Web浏览器发送加载页,然后稍后发送结果页

  •  2
  • Kurt W. Leucht  · 技术社区  · 15 年前

    我已经浪费了公司至少半天的时间在网上寻找答案,而我现在正忙得不可开交。我无法找出所有不同技术选择(长轮询、ajax流、comet、xmpp等)之间的区别,也无法在我的pc上获得一个简单的hello-world示例。

    我运行的是Apache2.2和ActivePerl5.10.0。这个解决方案完全可以接受javascript。我只想编写一个简单的perl-cgi脚本,当被访问时,它会立即返回一些html,告诉用户等待,或者发送一个动画gif。然后,在没有任何用户干预的情况下(没有鼠标点击或任何操作),我希望cgi脚本在以后的某个时候用他们查询的实际结果替换等待消息或动画gif。

    我知道这是很简单的事情,网站总是使用javascript来完成,但是我找不到一个可以剪切粘贴到我的机器上的perl工作示例。

    这是我从各种互联网资源中编译的简单hello world示例,但似乎不起作用。当我在我的web浏览器中刷新这个perl-cgi脚本时,它在5秒钟内什么也不打印,然后它打印请耐心等待的网页,而不是结果网页。因此,ajax xmlhttprequest显然不能正常工作。我做错什么了?

    #!C:\Perl\bin\perl.exe
    
    use CGI; 
    use CGI::Carp qw/fatalsToBrowser warningsToBrowser/; 
    
    sub Create_HTML {
        my $html = <<EOHTML;
    <html>
    <head>
      <meta http-equiv="pragma" content="no-cache" />
      <meta http-equiv="expires" content="-1" />
      <script type="text/javascript" >
    
    var xmlhttp=false;
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
    // JScript gives us Conditional compilation, we can cope with old IE versions.
    // and security blocked creation of the objects.
     try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
     } catch (e) {
      try {
       xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
       xmlhttp = false;
      }
     }
    @end @*/
    if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
        try {
            xmlhttp = new XMLHttpRequest();
        } catch (e) {
            xmlhttp=false;
        }
    }
    if (!xmlhttp && window.createRequest) {
        try {
            xmlhttp = window.createRequest();
        } catch (e) {
            xmlhttp=false;
        }
    }
    
      </script>
    
      <title>Ajax Streaming Connection Demo</title>
    </head>
    <body>
    
      Some header text.
      <p>
      <div id="response">PLEASE BE PATIENT</div>
      <p>
      Some footer text.
    
    </body>
    </html>
    
    EOHTML
        return $html;
      }
    
    my $cgi = new CGI;
    print $cgi->header;
    print Create_HTML();
    
    sleep(5);
    print "<script type=\"text/javascript\">\n";
    print "\$('response').innerHTML = 'Here are your results!';\n";
    print "</script>\n";
    
    4 回复  |  直到 15 年前
        1
  •  3
  •   friedo    15 年前

    如果您的进程依赖于查询字符串参数,那么简单的元刷新就足够了。例如,如果它们装载 http://yoursite.com/message?foo=1 ,则可以输出元标记,如:

    <meta http-equiv="refresh" content="0; http://yoursite.com/realquery?foo=1" />
    

    还有一些带有“请稍候”信息的HTML。这个 realquery 脚本将通过 message 将一直显示在屏幕上,直到 再查询 提供一些输出。

    如果查询依赖post数据,那么它会变得更复杂一些,因为您不能重定向post。但是,您可以输出一个带有一些隐藏字段的表单,并使用javascript提交它。例如:

    <script type="text/javascript">
        window.onload = function() { 
            document.getElementById( 'form_with_hidden_fields' ).submit();
        }
    </script>
    
    <form method="POST" action="realquery" id="form_with_hidden_fields">
        <input type="hidden" name="foo" value="1" />
        ...
    </form>
    
    Please wait while your query is processed...
    

    如果您对ajax解决方案感兴趣,这里有一个使用jquery的示例:

    $( '#submit-button' ).click( function() { 
        // show a "please wait" image
        $( '#status-div' ).html( '<img src="please_wait.gif" />' );  // animated gif
    
        // get form values
        var formdata = { foo: $( 'input#foo' ).val(),
                         ...
                       };
    
        // submit form via ajax:
        $.ajax( { type: "POST", url: "/realquery", data: formdata, success: function() { 
            $( '#status-div' ).html( '<img src="success.gif" />' );
        } );
    } );
    

    你可以把它附在一个表格上,比如:

    <form>
        <input type="text" name="foo" id="foo" />
        <input type="submit" id="submit-button" />
        <div id="status-div"> </div>
    </form>
    

    空的 status-div div将收到一个指向“请稍候”图像的图像标记(可以是动画gif)。当ajax查询完成时,它将被一个“success”图像替换。

        2
  •  2
  •   Sinan Ünür    15 年前

    Watching long processes through CGI 兰德尔·施瓦茨。

        3
  •  1
  •   Kurt W. Leucht    15 年前

    下面是一个使用friedo的http元刷新解决方案的完整工作示例。这不是我个人的首选解决方案,因为它可以修改浏览器中的url,还可以刷新整个网页。

    #!C:\Perl\bin\perl.exe
    use CGI; 
    use CGI::Carp qw/fatalsToBrowser warningsToBrowser/; 
    sub html_page {
        my ( $meta_string, $results_string ) = @_;
        my $html = <<EOHTML;
    <html>
    <head>
      $meta_string
      <title>Two Stage Web Page Demo</title>
    </head>
    <body>
      Some header text.
      <p>
      $results_string
      <p>
      Some footer text.
    </body>
    </html>
    EOHTML
        return $html;
      }
    
    my $cgi = new CGI;
    print $cgi->header;
    if ($cgi->param()) {
        if ($cgi->param('doResults') eq "true") {
            sleep(5);
            print html_page('', 'Here are your results!');
        }
    }
    else {
        my $meta_refresh = '<meta http-equiv="refresh" content="0; /cgi-bin/twoStageScript.pl?doResults=true" />';
        print html_page($meta_refresh, 'PLEASE BE PATIENT');
    }
    exit;
    
        4
  •  0
  •   Kurt W. Leucht    15 年前

    终于有了一个ajax版本。slow.pl文件是需要一段时间才能返回的文件。

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
        <head>
            <title>Two Stage web page demo using Ajax</title>
        </head>
        <body>
            <h1>Two Stage web page demo using Ajax</h1>
            <div id="result">
                Users input form goes here.
                <p>
                <input type="submit" value="Here is your submit button" id="load_basic" />
            </div>
            <script type="text/javascript" src="jquery-1.4.2.js"></script>
            <script type="text/javascript">
            $.ajaxSetup ({
                cache: false
            });
            var ajax_load = "Please be patient, this could take a while. <p> <img src='img/load.gif'/>";
    
            //  load() function
            $("#load_basic").click(function(){
                $("#result").html(ajax_load).load("/cgi-bin/slow.pl");
            });
            </script>
        </body>
    </html>