Как написать javascript на стороне клиента, чтобы получить и проанализировать ответ "chunked" во времени? - программирование

Как написать javascript на стороне клиента, чтобы получить и проанализировать ответ "chunked" во времени?

Я использую платформу воспроизведения, чтобы генерировать фрагментированный ответ. Код:

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 секунд, когда все полученные данные.

Как получить поток и обработать данные во времени?

4b9b3361

Ответ 1

jQuery не поддерживает это, но вы можете сделать это с помощью простого XHR:

var xhr = new XMLHttpRequest()
xhr.open("GET", "/test/chunked", true)
xhr.onprogress = function () {
  console.log("PROGRESS:", xhr.responseText)
}
xhr.send()

Это работает в всех современных браузерах, включая IE 10. Спецификация W3C здесь.

Недостатком здесь является то, что xhr.responseText содержит накопленный отклик. Вы можете использовать подстроку на нем, но лучше всего использовать атрибут responseType и использовать slice на ArrayBuffer.

Ответ 2

событие success будет срабатывать при завершении полной передачи данных и закрытии соединения с кодом ответа 200. Я считаю, что вы должны реализовать собственное onreadystatechanged событие и увидеть пакеты данных по мере их появления.

Ответ 3

Вскоре мы сможем использовать ReadableStream API (MDN docs здесь). Код ниже, похоже, работает с 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();
        });
    }
});

Ответ 4

Нет, вы не можете. Механизм ответа HTTP (включая сжатие и chunking) абстрагируется от JavaScript в браузере.