即使在浏览器窗口关闭后,也继续使用setTimeout执行AJAX

时间:2014-07-27 06:35:31

标签: javascript php jquery ajax casperjs

我有一个带有AJAX请求的PHP页面到另一个PHP页面,该页面包含一个casperJS脚本,由一个按钮点击触发,然后每60秒执行一次。

我希望能够关闭浏览器窗口但仍然继续运行AJAX请求,直到按下“停止”按钮。

我已经看到了关于这个主题的一些帖子

  1. Will a script continue to run even after closing a page?
  2. How can I make setInterval also work when a tab is inactive in Chrome?
  3. Scripting events no longer fire when a user leaves site or closes browser even though app is still active
  4. 他们提到了PHP ignore_user_abort(),但这些主要关注的是他们的脚本需要很长时间才能执行,他们希望通过关闭浏览器窗口来防止提前终止。

    目前,我的PHP站点设置了casperJS脚本的方式,我接收到.txt文件的日志更新,以及发生任何错误时的电子邮件,所以我能够看到脚本是否正在运行或不。

    如果我启动AJAX请求并快速关闭浏览器窗口,那么一个AJAX请求将完成并登录.txt文件,但后续的setTimeout将被忽略。

    我希望能够返回已关闭的窗口并仍然看到AJAX返回的当前状态,并且还能够在那时停止脚本(就好像我从未离开/关闭浏览器一样)窗口)。这可能吗?

    我当前的AJAX请求的PHP代码:

    <!DOCTYPE html>
    <html>
      <head>
        <link rel="stylesheet" href="style.css" type="text/css" media="screen, projection"/>
        <script src="jquery-2.1.1.min.js" type="text/javascript"></script>
        <script type="text/javascript" language="javascript" src="jquery.dropdownPlain.js"></script>
        <title>CasperJS Automated Testing Unit</title>
      </head>
      <center>
      <body>
      <div id="mainContent">
    <p>Welcome to the CasperJS Automated Testing Unit</p>
      <button id="button_AJAX">Run CasperJS</button>
      <button id="button_STOP" onclick="myStopFunction()">Stop CasperJS</button>
      </div>
      <br>
      <div id="loading"></div>
    <script type="text/javascript">
      $('#button_AJAX').click(function executecasperJS() {
         $('#loading').html('<img src="rays.gif"><br><i>Web harvesting in progress; please wait for test results.</i>');  
            $.ajax({  
              type: "GET",
              dataType: "text",
              url: "phpwithCasperJS.php",
          success: function (data) {        
                      $('#loading').html(data);
              } 
          }); 
    timeout = setTimeout(executecasperJS,60000);  
    });
        $("#button_AJAX").click(function() {$("#button_AJAX").text("CasperJS Executed");});
      $("#button_STOP").click(function() {$("#button_AJAX").text("Run CasperJS");});
      function myStopFunction() {
          clearTimeout(timeout);
      }
    </script>
    </div>
      <div id="page-wrap">
              <ul class="dropdown">
              <li><a href="#">CasperJS Logs</a>
                <ul class="sub_menu">
                   <li><a href="casperjs_log.txt" target="_blank">Testing Log</a></li>
                   <li><a href="casperjs_error.txt" target="_blank">Error Log</a></li>
    
            </ul>
    
      </div>
    </center>
      </body>
    </html> 
    

    包含我的casperJS脚本的PHP:

     <?php
    date_default_timezone_set('America/Managua');
    $date = date('m/d/Y h:i:s a', time());
        $time_start = microtime(true);
        $output = exec("/usr/local/bin/casperjs /path/to/script/casperJScript.js");
            if (strpos($output, 'Check for fail message') === FALSE) {
                require_once('../class.phpmailer.php');
        $mail             = new PHPMailer();
        $mail->IsSMTP();     
        $mail->SMTPDebug  = 1;                   
        $mail->SMTPAuth   = true;                  
        $mail->SMTPSecure = "ssl";                
        $mail->Host       = "smtp.gmail.com";      
        $mail->Port       = 465;                   
        $mail->IsHTML(true);     
        $mail->Username   = "emailaddress";  
        $mail->Password   = "password";            
        $mail->SetFrom('emailaddress');
        $mail->AddReplyTo("emailaddress");
        $mail->Subject    = "casperJS: Server failure occured on $date";
        $mail->Body    = "Body";
        $mail->AddAddress("emailaddress");
                if(!$mail->Send()) {
                } else {
                echo '<span style="color:#FF0000">The server has gone 100% failure and an email with the error has been sent.</span>';
                $myfile = fopen("../casperjs_error.txt", "a") or die("Unable to open file!");
                $txt = "ERROR log: $output on $date" . PHP_EOL ;
                fwrite($myfile, $txt);
                fclose($myfile);
                  echo "<br />";
                  echo "<br />";
                }   
            }
            echo "Test Results: $output";
            $time_end = microtime(true);
            $time = $time_end - $time_start;
            echo "<br />";
            echo "<br />";
            echo "Test completed in $time seconds\n on $date";
            $myfile = fopen("../casperjs_log.txt", "a") or die("Unable to open file!");
            $txt = "Log: $output on $date" . PHP_EOL ;
            fwrite($myfile, $txt);
            fclose($myfile);
        ?>
    

2 个答案:

答案 0 :(得分:2)

在浏览器窗口关闭后,无法触发AJAX请求。

在任何情况下,为什么要依赖定期的AJAX(HTTP)请求来继续某些服务器端进程?不要那样做。

相反,组织在服务器端启动长时间运行的进程(可能是为了响应客户端请求)。然后,您只需要在客户端上发出HTTP(AJAX或其他)请求,即可查看服务器端作业的“进度”。

答案 1 :(得分:0)

一旦浏览器不再在当前页面的上下文中执行,任何可能仍在执行的JavaScript都将被终止。通常,您会注意到这种行为,因为用户按下了停止按钮,关闭了窗口或移动到了其他页面。例如,当我对堆栈溢出(和相关站点)进行投票时,如果我立即投票(向上或向下),我通常会在手机上收到错误,然后点击标题栏返回到问题列表。但是,服务器通常会完成请求,因为当我回到问题列表时,尽管出现错误,但投票已经反映出来。

请注意,对于短请求,只要服务器收到整个HTTP有效负载,它就会执行完成请求,尽管用户可能永远不会意识到这一事实。通常,卸载页面会产生以下影响:任何&#34; onunload&#34;或类似的事件被触发,任何现有的AJAX请求都会自动失败,就像互联网连接已经终止(例如关闭WiFi或网络适配器),以及所有与&#34;卸载&#34;终止,例如&#34; onclick&#34;,&#34; onkeypress&#34;等,特别包括&#34; setTimeout&#34;和&#34; setInterval&#34;事件。如果您必须知道发生了某些事情,可以尝试弹出窗口,但是用户弹出设置或弹出窗口阻止程序可能会禁止这一个最终的开局,以便知道该页面将被卸载。

总之,客户很可能不会向服务器发送任何最终通知,服务器通常不会注意到客户端的消失。你可以通过使用Comet来减少这种影响,Comet是一种长轮询方法,它至少能够通知服务器一个连接关闭事件,这是你可以得到的最接近的事件&#34;保证&#34;服务器会注意到页面的最终消失。但是,Comet有其自身的局限性,包括服务器端资源的使用增加,以及对不同类型事件的敏感性,包括互联网连接的丢失(即,&#39) ;无法检测关闭页面的用户与完全失去连接之间的差异,您将看到的是连接器上的连接丢失。)