8

I'm sending chunked data from a NodeJS application back to the browser. The chunks are really json strings. Problem I'm having is that every time the onprogress function is called, it adds on a string of the complete data. Meaning that response chunk number two, is appended to response chunk number one, and so on. I'd like to get ONLY the "just now" received chunk.

Here's the code:

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

So really, the contents of xhr.responseText contains, when the third response comes, also the response text for the first and the second response. I've checked what the server is sending, and it doesn't look like there's a problem there. Using Node with Express, and sending with res.send("...") a couple of times. Also headers are set like so:

res.setHeader('Transfer-Encoding', 'chunked');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.set('Content-Type', 'text/json');
Daniel Setréus
  • 552
  • 4
  • 16
  • This is not how the `onprogress xhr.responseText` API works. Maybe JSONify all arguments passed into the `onprogress` function invocation ? Maybe that can help find other fields to assist in the goal, or track total bytes processed so far and cut up the string/binary data yourself ? – Darryl Miles Nov 10 '15 at 17:33
  • 1
    FWIW you really should not set `Transfer-Encoding` header yourself from application. This should be a transparent matter the XHR handles better itself, this helps it deal with different HTTP versions and other transport related concerns properly. – Darryl Miles Nov 10 '15 at 17:37

1 Answers1

11

This index based approach works for me:

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

Inspired by https://friendlybit.com/js/partial-xmlhttprequest-responses/

Thomas Chille
  • 156
  • 3
  • 8