1

編集済み

$.ajax()次のphpスクリプトを呼び出すajax呼び出し(を使用)があります。

for ($i=0;$i<40;$i++) {
    echo " ";
    flush();
    if (connection_aborted()) {
        log_message('error','CONNECTION IS ABORTED!!!!!');
        exit;
    }
    else {
        log_message('error','connection not aborted :(');
    }
    sleep(1);
}

これは 40 秒間続きます。

呼び出しをトリガーしたブラウザー ウィンドウを閉じると、明示的に文字列を送信してバッファーをフラッシュしたとしても、connection_aborted() false が返されます。

ここに答えがある人はいますか?

4

1 に答える 1

7

「ignore_user_abort(true);」を追加する必要があります。PHP スクリプトの上に追加し、スクリプトから何かをエコーし​​た後に "ob_flush()" を呼び出します (理由については、PHP flush() のマニュアル ページを参照してください)。作業例 (概念実証):

<?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);
}

PS connection_status() は、接続がまだアクティブな場合は 0 を返し、接続が閉じている場合は 1 を返します。

編集:

私の悪い。サーバー/php の設定によっては、flush() と ob_flush() の両方を呼び出します (flush() のマニュアル ページ、上記のリンク、およびこのトピックの回答を参照してください)。次のコードは、WAMP で PHP 5.3.8 (flush() を呼び出さなくても動作) でテストされ、現在は Ubuntu で PHP 5.3.10 でテストされています。ob_flush() の前に flush() 呼び出しが必要です。

テスト用の完全なコード:

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);
}

index.html ページを呼び出し、タブまたはブラウザ全体を閉じると、log.txt ファイルに次の情報が表示されます。

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
于 2012-08-20T22:23:22.837 に答える