【问题标题】:How to send web browser a loading page, then some time later a results page如何向网络浏览器发送加载页面,然后在一段时间后发送结果页面
【发布时间】:2011-02-04 14:23:40
【问题描述】:

我已经浪费了我公司至少半天的时间在 Internet 上搜索答案,而我正忙得不可开交。我无法弄清楚所有不同技术选择(长轮询、ajax 流、comet、XMPP 等)之间的区别,也无法在我的 PC 上运行一个简单的 hello world 示例。

我正在运行 Apache 2.2 和 ActivePerl 5.10.0。对于这个解决方案,JavaScript 是完全可以接受的。我要做的就是编写一个简单的 Perl CGI 脚本,当访问它时,它会立即返回一些 HTML,告诉用户等待或者发送一个动画 GIF。然后,无需任何用户干预(无需单击鼠标或任何操作),我希望 CGI 脚本稍后将等待消息或动画 GIF 替换为其查询的实际结果。

我知道这很简单,网站一直使用 JavaScript 来做这件事,但是我找不到一个可以剪切并粘贴到我的机器上的可以在 Perl 中运行的工作示例。

这是我从各种 Internet 资源编译的简单 Hello World 示例,但它似乎不起作用。当我在我的网络浏览器中刷新这个 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";

【问题讨论】:

    标签: javascript ajax perl streaming cgi


    【解决方案1】:

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

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

    还有一些带有“请稍候”消息的 HTML。 realquery 脚本将实际执行查询,message 的 HTML 输出将保留在屏幕上,直到 realquery 提供一些输出。

    如果查询依赖于 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 查询完成时,它会被“成功”图像替换。

    【讨论】:

    • 好的,成功了。感谢您的解决方案!如果没有人回答 Ajax 解决方案,我将使用此解决方案。这样做的好处是只刷新网页的结果部分,而无需在浏览器上发送和刷新整个网页。
    • 元重定向解决方案的另一个缺点是它会将 URL 与 Web 浏览器中的查询字符串混淆,我相信 Ajax 解决方案在更新部分内容时实际上不会更改 URL网页。
    • 我添加了一个使用 jQuery 的 Ajax 示例。
    • 我尝试了您的 jquery 示例,但无法使其正常工作。您能否发布一个完整的工作示例而不是简短的 sn-ps。无需使用动画 GIF ......只需在其中放置一些文本。我不确定我是否将您的代码 sn-ps 放在正确的位置并正确使用它们。我以前从未使用过 Ajax 或 Jquery。
    【解决方案2】:

    请参阅 Randal Schwartz 的 Watching long processes through CGI

    【讨论】:

    • 这篇文章很有帮助!
    【解决方案3】:

    这是一个使用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】:

      终于得到了一个 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>
      

      【讨论】:

        猜你喜欢
        • 2018-05-13
        • 2022-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-14
        • 1970-01-01
        • 2018-12-25
        • 2016-02-14
        相关资源
        最近更新 更多