Jos*_*osh 70 ajax jquery javascript-events long-polling http-streaming
我已经阅读了这个问题,但它并没有完全回答我的问题.不幸的是,自从我上次查看AJAX以来,看起来XHR对象中的内容发生了变化,因此responseText在完成填充之前不再可以直接访问.
我必须编写一个使用AJAX(最好是jQuery,但我愿意接受建议)的页面来从我无法控制的服务器通过HTTP检索CSV数据.响应数据可能非常大; 一兆字节的文本并不少见.
服务器是流友好的.是否有任何方法可以直接从JavaScript返回数据流?
我可以选择编写一些生活在中间的PHP代码并使用某种"Comet"技术(长轮询,EventSource等),但我希望尽可能避免这种情况.
如果它是相关的,假设这个问题用户有最新版本的Firefox/Chrome/Opera和旧的浏览器兼容性不是问题.
Ale*_*nch 66
输出文本或HTML时,这非常简单.以下是一个例子.
(如果尝试输出JSON,你会遇到问题,我将进一步解决这个问题.)
header('Content-type: text/html; charset=utf-8');
function output($val)
{
echo $val;
flush();
ob_flush();
usleep(500000);
}
output('Begin... (counting to 10)');
for( $i = 0 ; $i < 10 ; $i++ )
{
output($i+1);
}
output('End...');
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE>
<html>
<head>
<title>Flushed ajax test</title>
<meta charset="UTF-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
var last_response_len = false;
$.ajax('./flushed-ajax.php', {
xhrFields: {
onprogress: function(e)
{
var this_response, response = e.currentTarget.response;
if(last_response_len === false)
{
this_response = response;
last_response_len = response.length;
}
else
{
this_response = response.substring(last_response_len);
last_response_len = response.length;
}
console.log(this_response);
}
}
})
.done(function(data)
{
console.log('Complete response = ' + data);
})
.fail(function(data)
{
console.log('Error: ', data);
});
console.log('Request Sent');
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
实际上不可能以递增方式加载单个JSON对象(在它完全加载之前),因为在您拥有完整对象之前,语法将始终无效.
但是如果你的响应有一个接一个的多个 JSON对象,那么它们可以一次加载一个,因为它们是从管道下来的.
所以我调整了上面的代码......
将PHP FILE第4行更改echo $val;为echo '{"name":"'.$val.'"};'.这会输出一系列JSON对象.
将HTML FILE行24更改console.log(this_response);为
this_response = JSON.parse(this_response);
console.log(this_response.name);
Run Code Online (Sandbox Code Playgroud)
请注意,此基本代码假定进入浏览器的每个"块"都是有效的JSON对象.情况并非总是如此,因为您无法预测数据包将如何到达 - 您可能需要根据分号分割字符串(或者提出另一个分隔符字符).
application/json难道不是为了改变你的头来application/json-我做了这一点,它让我谷歌搜索3天.当响应类型application/json为时,浏览器会等待响应完成,如完全完成.然后解析完整响应以检查它是否是实际的JSON.但是我们的FULL响应是{...};{...};{...};无效的JSON.该jqXHR.done方法假定存在错误,因为无法将完整响应解析为JSON.
如评论中所述,您可以使用以下命令在客户端禁用此检查:
$.ajax(..., {dataType: "text"})
Run Code Online (Sandbox Code Playgroud)
希望有些人觉得这很有用.
Pet*_*tah 32
使用XMLHttpRequest.js
https://github.com/ilinsky/xmlhttprequest
http://code.google.com/p/xmlhttprequest
要使用PHP进行长轮询:
output.php:
<?php
header('Content-type: application/octet-stream');
// Turn off output buffering
ini_set('output_buffering', 'off');
// Turn off PHP output compression
ini_set('zlib.output_compression', false);
// Implicitly flush the buffer(s)
ini_set('implicit_flush', true);
ob_implicit_flush(true);
// Clear, and turn off output buffering
while (ob_get_level() > 0) {
// Get the curent level
$level = ob_get_level();
// End the buffering
ob_end_clean();
// If the current level has not changed, abort
if (ob_get_level() == $level) break;
}
// Disable apache output buffering/compression
if (function_exists('apache_setenv')) {
apache_setenv('no-gzip', '1');
apache_setenv('dont-vary', '1');
}
// Count to 20, outputting each second
for ($i = 0;$i < 20; $i++) {
echo $i.str_repeat(' ', 2048).PHP_EOL;
flush();
sleep(1);
}
Run Code Online (Sandbox Code Playgroud)
run.php:
<script src="http://code.jquery.com/jquery-1.6.4.js"></script>
<script src="https://raw.github.com/ilinsky/xmlhttprequest/master/XMLHttpRequest.js"></script>
<script>
$(function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/longpoll/', true);
xhr.send(null);
var timer;
timer = window.setInterval(function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
window.clearTimeout(timer);
$('body').append('done <br />');
}
$('body').append('state: ' + xhr.readyState + '<br />');
console.log(xhr.responseText);
$('body').append('data: ' + xhr.responseText + '<br />');
}, 1000);
});
</script>
Run Code Online (Sandbox Code Playgroud)
这应输出:
state: 3
data: 0
state: 3
data: 0 1
state: 3
data: 0 1 2
state: 3
data: 0 1 2 3
state: 3
data: 0 1 2 3 4
...
...
...
state: 3
data: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
state: 3
data: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
state: 3
data: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
done
state: 4
data: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Run Code Online (Sandbox Code Playgroud)
对于IE,您需要查看XDomainRequest
http://msdn.microsoft.com/en-us/library/cc288060(VS.85).aspx
sco*_*kel 20
你会想要直接使用javascript.原因是你想要不断轮询而不是等待回调.你不需要jQuery,这很简单.他们在Ajax Patterns网站上有一些很好的源代码.
从本质上讲,您只需要跟踪响应中的最后位置,并定期轮询该位置之外的更多文本.您的情况有所不同,您可以订阅完整的活动并停止投票.
g19*_*tic 16
既然你说你的服务器是流友好的(异步)并且正在寻找一个jquery解决方案,你有没有检查过jQuery Stream插件?
| 归档时间: |
|
| 查看次数: |
74814 次 |
| 最近记录: |