开发者

How to write javascript in client side to receive and parse `chunked` response in time?

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();
        });
    }
});


the success event would fire when the complete data transmission is done and the connection closed with a 200 response code. I believe you should be able to implement a native onreadystatechanged event and see the data packets as they come.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜