IFrame Comet response contains no data
I'm experimenting with Comet and I'm stuck with implementing it via a hidden IFrame ("forever frame".
This is my index.html:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
cometResponse = function() {
var debugOut = document.getElementById('debugOutput');
return function(response) {
debugOut.innerHTML = response.number;
}
}
</script>
</head>
<body>
<div id="debugOutput"></div>
<iframe src="comet.php"></iframe>
</body>
</html>
And this is the comet.php file:
<?php
set_time_limit(0);
header('Content-Type: text/html');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Transfer-Encoding: chunked');
flush();
ob_flush();
$response = '<script type="text/javascript">
parent.cometResponse({
number: %1$d
});
</script>';
for ($i = 0; $i < 2; $i++) {
sleep(1);
$data = sprintf($response, $i);
$output = strtoupper(dechex(strlen($data)))."\r\n".$data."\r\n";
echo $output;
flush();
ob_flush();
}
echo "0\r\n\r\n";
After loading the page, the browser seems to "wait" for the response. After a few seconds, Firebug shows an empty response with these response headers:
HTTP/1.1 200 OK
Date: Mon, 26 Jul 2010 09:34:04 GMT
Server: Apache/2.2.14 (Win32) PHP/5.2.12
X-Powered-By: PHP/5.2.12
Cache-Control: no-cache, must-revalidate
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Transfer-Encoding: chunked
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html;charset=ISO-8859-2
Since the response is treated as empty, the tag that should be in the response doesn't get executed either.
However, if I remove the "Transfer-Encoding: chunked" h开发者_JAVA技巧eader, the content is sent to the browser correctly but all in one big piece at the end of the script, as expected.
I just can't find what's going wrong here.
Two guesses:
Content-Encoding: gzip
Maybe mod_gzip does not work correctly? Have you tried on annother host?
- Maybe Firefox ignores the code, if it is not within < html>
This might help someone else, here is how I solved it:
<?php
header('Content-Encoding: chunked');
header('Transfer-Encoding: chunked');
header('Content-Type: text/html');
header('Connection: keep-alive');
header('Cache-Control: no-cache, must-revalidate');
flush();
set_time_limit(0);
function chunk($data) {
echo sprintf("%x\r\n%s\r\n", strlen($data), $data);
flush();
ob_flush();
}
// Code to output data here.
// The following loop is an example.
for($i = 0; $i < 5; $i++) {
chunk('<script type="text/javascript">window.top.test();</script>');
sleep(1);
}
chunk('');
?>
It needed an empty chunk at the end of the output.
Then you can simply output data by calling the function chunk
like this:
chunk('data');
精彩评论