Ответ XMLHttpRequest, разделенный на фрагменты, выполняется чтение только последнего ответа

Я отправляю фрагментированные данные из приложения NodeJS обратно в браузер. Фрагменты на самом деле представляют собой строки json. У меня проблема в том, что каждый раз, когда вызывается функция onprogress, она добавляет строку полных данных. Это означает, что фрагмент ответа номер два добавляется к фрагменту ответа номер один и так далее. Я хотел бы получить ТОЛЬКО полученный фрагмент "только что".

Вот код:

    console.log("Start scan...");
    var xhr = new XMLHttpRequest();
    xhr.responseType = "text";
    xhr.open("GET", "/servers/scan", true);
    xhr.onprogress = function () {
        console.log("PROGRESS:", xhr.responseText);
    }
    xhr.send();

Так что действительно, содержимое xhr.responseText содержит, когда приходит третий ответ, также текст ответа для первого и второго ответа. Я проверил, что отправляет сервер, и не похоже, что там есть проблема. Использование Node с Express и отправка с помощью res.send("...") пару раз. Также заголовки устанавливаются так:

res.setHeader('Transfer-Encoding', 'chunked');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.set('Content-Type', 'text/json');

person Daniel Setréus    schedule 10.11.2015    source источник
comment
onprogress xhr.responseText API работает иначе. Может быть, JSONify все аргументы, переданные в вызов функции onprogress? Может быть, это может помочь найти другие поля, которые помогут в достижении цели, или отследить общее количество обработанных байтов и самостоятельно разрезать строковые/двоичные данные?   -  person Darryl Miles    schedule 10.11.2015
comment
FWIW, вам действительно не следует самостоятельно устанавливать заголовок Transfer-Encoding из приложения. Это должно быть прозрачным вопросом, с которым XHR лучше справляется сам, это помогает ему правильно справляться с различными версиями HTTP и другими проблемами, связанными с транспортом.   -  person Darryl Miles    schedule 10.11.2015


Ответы (1)


Этот подход на основе индекса работает для меня:

var last_index = 0;
var xhr = new XMLHttpRequest();
xhr.open("GET", "/servers/scan");
xhr.onprogress = function () {
    var curr_index = xhr.responseText.length;
    if (last_index == curr_index) return; 
    var s = xhr.responseText.substring(last_index, curr_index);
    last_index = curr_index;
    console.log("PROGRESS:", s);
};
xhr.send();

На основе https://friendlybit.com/js/partial-xmlhttprequest-responses/

person Thomas Chille    schedule 18.07.2016