ajax 如何在客户端编写javascript以及时接收和解析`chunked`响应?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6789703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 11:02:35  来源:igfitidea点击:

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

ajaxchunked

提问by Freewind

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.

当我使用浏览器访问时http://localhost:9000/test/chunk,我可以看到显示的数据每秒增加。但是,当我编写一个 javascript 函数来接收和处理数据时,发现它会阻塞直到收到所有数据。

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.

当收到所有数据时,我可以看到 10 秒后弹出一个消息框。

How to get the stream and handle the data in time?

如何获取流并及时处理数据?

回答by phil pirozhkov

jQuery doesn't support that, but you can do that with plain XHR:

jQuery 不支持,但你可以用普通的 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.

这适用于所有现代浏览器,包括 IE 10。此处为W3C 规范。

The downside here is that xhr.responseTextcontains an accumulated response. You can use substring on it, but a better idea is to use the responseTypeattribute and use sliceon an ArrayBuffer.

这里的缺点是xhr.responseText包含累积的响应。您可以在其上使用 substring,但更好的主意是使用responseType属性并sliceArrayBuffer.

回答by rinat.io

Soon we should be able to use ReadableStreamAPI (MDN docs here). The code below seems to be working with Chrome Version 62.0.3202.94:

很快我们应该能够使用ReadableStreamAPI(此处为 MDN 文档)。下面的代码似乎适用于 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();
        });
    }
});

回答by kishu27

the successevent 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 onreadystatechangedevent and see the data packets as they come.

success当完整的数据传输完成并且连接以 200 响应代码关闭时,将触发该事件。我相信您应该能够实现本机onreadystatechanged事件并看到数据包。