connection_aborted() does not work on ajax calls

后端 未结 1 1328
囚心锁ツ
囚心锁ツ 2021-01-25 10:13

EDITED

I\'ve got an ajax call (using $.ajax()) which calls the following php script.

for ($i=0;$i<40;$i++) {
    echo \" \";
    flu         


        
相关标签:
1条回答
  • 2021-01-25 10:51

    You will need to add "ignore_user_abort(true);" on top of the PHP script, and to call "ob_flush()" after echoing something from script (For why see PHP flush() man page). Working example (proof of concept):

    <?php
    
    ignore_user_abort(true);
    
    function log_message($s, $ss) {
      $myFile = "log.txt";
      $fh = fopen($myFile, 'a') or die("can't open file");
      $stringData = $s . ": " . $ss . "\n";
      fwrite($fh, $stringData);
      fclose($fh);
    }
    
    
    
    for ($i=0;$i<5;$i++) {
    
        echo "<br>";
        //flush();
        ob_flush();
    
        if (connection_aborted()) {
            log_message('error1', connection_status());
            exit;
        }
        else {
            log_message('error2', connection_status());
        }
    
        sleep(1);
    }
    

    P.S. connection_status() returns 0 if connection is still active, and in case of closed one returns 1.

    EDIT:

    My bad. Call both flush() and ob_flush() (please read flush() man page, link above, and answers from this topic), or otherwise might not work, depending on server/php configuration. The following code was tested on WAMP with PHP 5.3.8 (works without calling flush()), and now on Ubuntu with PHP 5.3.10. where flush() call before ob_flush() is necessary.

    Full code for testing:

    index.html:

     <html>
      <head>
        <script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
    
        <script>
    
          $(document).ready(function() {
    
            $.ajax({
              url: "script.php",
              context: document.body
            }).done(function(data) { 
             alert(data);
            });
    
          })
    
        </script>
    
      </head>
    
      <body>
      </body>
    
    </html>
    

    script.php:

    ignore_user_abort(true);
    
    function log_message($type, $message, $file = 'log.txt') {
        $fh = fopen($file, 'a') or die("can't open file");
    
        $conn_status = connection_status();
    
        if($conn_status === CONNECTION_NORMAL) {
            $status = 'normal';
        } elseif($conn_status  === CONNECTION_ABORTED) {
             $status = 'aborted';
        } else {
            $status = 'timeout';
        }
    
        $aborted = connection_aborted() ? 'yes' : 'no';
    
        $data  = $type . ': ' . $message . "\n";
        $data .= 'Connection status: ' . $status . "\n";
        $data .= 'Aborted: ' . $aborted . "\n\n\n";
    
        fwrite($fh, $data);
        fclose($fh);
    }
    
    
    
    for ($i = 0; $i < 10; $i++) {
    
        echo "<br>";
        flush();
        ob_flush();
    
        if (connection_aborted()) {
            log_message('Error', 'Connection closed by user!');
            exit;
        }
        else {
            log_message('Info', 'Everything is fine. Move along...');
        }
    
        sleep(1);
    }
    

    After you call index.html page, and close tab or whole browser you should see in log.txt file next info:

    Info: Everything is fine. Move along...
    Connection status: normal
    Aborted: no
    
    
    Info: Everything is fine. Move along...
    Connection status: normal
    Aborted: no
    
    
    Info: Everything is fine. Move along...
    Connection status: normal
    Aborted: no
    
    
    Error: Connection closed by user!
    Connection status: aborted
    Aborted: yes
    
    0 讨论(0)
提交回复
热议问题