我正在使用play框架,以生成分块响应。代码是:
class Test extends Controller {
public static void chunk() throws InterruptedException {
for (int i = 0; i < 10; i++) {
String data = repeat("" + i, 1000);
response.writeChunk(data);
Thread.sleep(1000);
}
}
}
当我使用浏览器访问http://localhost:9000/test/chunk
时,我可以看到显示的数据每秒都在增加。但是,当我编写一个javascript函数来接收和处理数据时,发现它会阻塞直到收到所有数据。
代码是:
$(function(){
$.ajax(
"/test/chunked",
{
"success": function(data, textStatus, xhr) {
alert(textStatus);
}
}
);
});
我收到所有数据后,10秒后会看到一个消息框。
如何及时获取流并处理数据?
答案 0 :(得分:63)
jQuery不支持,但你可以用普通的XHR来做到这一点:
var xhr = new XMLHttpRequest()
xhr.open("GET", "/test/chunked", true)
xhr.onprogress = function () {
console.log("PROGRESS:", xhr.responseText)
}
xhr.send()
这适用于all modern browsers,包括IE 10. W3C规范here。
这里的缺点是xhr.responseText
包含累积的响应。您可以在其上使用子字符串,但更好的方法是使用responseType属性并在slice
上使用ArrayBuffer
。
答案 1 :(得分:4)
很快我们就可以使用ReadableStream
API(MDN docs here)了。以下代码似乎与Chrome版本62.0.3202.94一起使用:
fetch(url).then(function (response) {
let reader = response.body.getReader();
let decoder = new TextDecoder();
return readData();
function readData() {
return reader.read().then(function ({value, done}) {
let newData = decoder.decode(value, {stream: !done});
console.log(newData);
if (done) {
console.log('Stream complete');
return;
}
return readData();
});
}
});
答案 2 :(得分:0)
当完成数据传输并且连接以200响应代码关闭时,success
事件将触发。我相信您应该能够实现本机onreadystatechanged
事件并查看数据包。