10代と話して驚いたこと

jqueryのajaxを使って通信先のphpが発行するhtmlを受信して受信側の<div id="data"></div>に
表示させているのですが、通信先のphpが処理して生成したhtmlの途中結果を受信して
表示させるにはどのようにすれば良いのでしょうか?

例えば通信先のphpを

<?php
ob_start();
for ( $i = 1; $i <= 100000; $i++ ) {
 if ($i % 100 == 0) {
  echo "■";
 }
 @ob_flush();
 @flush();
 usleep(30000);
}
?>

このようにして受信側を

<div id="data">■■■</div>

というようにプログレスバーみたいに次々と■を増やしていきたいのですが、実行してみると最終結果の

<div id="data">■■■■■■■■■■■■■■■■■■■■■■■■(…省略)</div>

だけが出力されてしまいます。

どのようにすれば良いのか教えて頂きたいです。
どうぞよろしくお願い致します。

A 回答 (2件)

一応、補足。



CGIを使わない静的なファイルであればApacheなどのウェブサーバーが自動的にcontent_lengthを計算してくれますが、
動的な生成ではプログラム終了まで送出サイズがわからないため、content-lengthが計算できません。
そのため、自分で計算する処理を入れなければなりません。
CGI(PHP)からcontent-lengthを送出する方法ですが、以下のような考え方で行ってください。

バッファにすべてのデータを貯めておく。
  global $buffer;
  $buffer='<div id="data">';
  $buffer.='■';
  $buffer.='</div></html>';
バッファサイズを測り、ヘッダを生成する
  $bytes=strlen($buffer);
  header('content-length: ' . $bytes);
データを送出する。
  echo $buffer;

---------------------
もう一つの方法として、Comet(ロングポーリング)を使う方法があります。

PHP側の処理をsleepさせずに、一旦終了させます。
その後JavaScriptで通常のonreadystatechangeの処理(受信完了処理)を行い、直後(または一定時間おいて)にもう一度サーバーにアクセスします。
こうする事で、アクセス完了処理が何回も行われる事になりますので、(擬似的な)リアルタイム更新が可能になります。

詳しくは「ajax comet」で検索してみてください。

クライアント側で一定時間待機後にアクセスする通常のポーリング
(<meta name="refresh" content="10">のAjax版)
なら、Cometほどサーバー負荷はありません。
こちらの方がよく使われます。
チャットルームなどがこのポーリングです。

Twitterの「新しい発言」が自動的に増えていくのとか、スクロールするごとに次ページの内容が表示されていくというのも、
画面に追加するという点ではポーリングと変わりありません。
ぶっちゃけ、単発のAjax通信は「Ajax」と呼ぶに対して、連続するAjax通信に違う名前を付けただけです。

-----------------
純粋な双方向通信を行う方法

ブラウザもサーバーも、両方が対応している必要がありますが、WebSocketを使用する方法があります。
要はブラウザが行っている通信行程を全てJavaScriptで記述し、
サーバー側のプログラムは、Apache(Apache上で動くものではなく、Apacheそのもの)を作るような物です。
そのため、一般のレンタルサーバーでは使えません。

「websocket」で検索してください。
    • good
    • 0

XMLHttpRequest2であれば、


.onprogressイベントハンドラで処理すれば、通信途中の状況を取得する事が出来ます。
(ブラウザが対応していれば)

http://dvcs.w3.org/hg/progress/raw-file/tip/Over …
ProgressEventインターフェースで受け取れるのは受信バイト数、総バイト数のみです。

総バイト数はおそらくcontent-lengthヘッダだと思います。
そのため、CGI等から出力する場合でcontent-transfer-encodingヘッダがchunckedになっていると、content-lengthヘッダを生成できなかったりchunkのバイト数だけになっていることがあるため、総バイト数が0になるか非常に不安定、または常にtotalとloadedが同じ値になると思います。


jQueryはプラグインでonprogressに対応しているようです。
https://github.com/kpozin/jquery-ajaxprogress
探せば同様のプラグインが他にもあるかもしれません。


質問文のような、PHPの出力を逐次出力するという事はできません。(サーバーから受信したデータを受け取るプロパティがないため。)
バイト数から■の数を計算し、出力してください。
    • good
    • 0
この回答へのお礼

お教え下さってありがとうございます。

>質問文のような、PHPの出力を逐次出力するという事はできません。

そうなのですね。なんとなくできないだろうな…とは思っていたのですが…。

教えていただいた件ですが、自分には未知の部分が多く、これから勉強する上での
指標とさせて頂きたいと思います。
そのため、詳しくお返事できないことをお許し下さい。
ただ実現に向けて実行していくことは確かです。
そのとき再びわからないことがありましたらまた質問させて頂きたいと思います。

お礼日時:2012/11/24 15:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報