I'm using play framework, to generate chunked response. The code is:
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);
}
}
}
When I use browser to visit http://localhost:9000/test/chunk
, I can see the data displayed increased every second. But, when I write a javascript function to receive and handle the data, found it will block until all data received.
The code is:
$(function(){
$.ajax(
"/test/chunked",
{
"success": function(data, textStatus, xhr) {
alert(textStatus);
}
}
);
});
I can see a message box popped up after 10s, when all the data received.
How to get the stream and handle the data in time?
jQuery doesn't support that, but you can do that with plain XHR:
var xhr = new XMLHttpRequest()
xhr.open("GET", "/test/chunked", true)
xhr.onprogress = function () {
console.log("PROGRESS:", xhr.responseText)
}
xhr.send()
This works in all modern browsers, including IE 10. W3C specification here.
The downside here is that xhr.responseText
contains an accumulated response. You can use substring on it, but a better idea is to use the responseType attribute and use slice
on an ArrayBuffer
.
Soon we should be able to use ReadableStream
API (MDN docs here). The code below seems to be working with Chrome Version 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();
});
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With