[html5] XHR Questions

Domenic Denicola d at domenic.me
Thu Mar 17 11:21:56 PDT 2016

From: Help [mailto:help-bounces at lists.whatwg.org] On Behalf Of Gomer Thomas

> I have several questions about the XMLHttpRequest specification.
> (1) As far as I can tell, if the response is of type "text", then a partial response can be accessed during the transmission of the response. However, if the response is of any other type, then the response cannot be accessed until the transmission is finished. Why is that so? I have an application for which it is important to access partial responses while the transmission is in progress for a "blob" response (actually an ISO BMFF file). 

I am not sure why this was never added in the first place for blobs, where it was for text. (Maybe Anne, CC'ed, can clarify.)

However, we're trying to solve this going forward with a combination of the Fetch and Streams APIs:

- http://fetch.spec.whatwg.org/
- https://streams.spec.whatwg.org/

You can see an example at https://fetch.spec.whatwg.org/#fetch-api. However, note that this integration is currently only implemented in Chrome. (Other browsers implement fetch, but not yet the Response object's body property.)

A big advantage of Fetch + Streams over XHR's text mode is that even though XHR's text allows you to access the body incrementally, it still retains the entire response body in memory. Thus, for a 1 GiB response, your memory usage will slowly grow from 0 to 1 GiB. Fetch + streams allows you to consume chunks as they arrive, so that at any given time you only hold a chunk's worth of bytes (usually between a few KiB and a few MiB, depending on network conditions) in memory.

> (2) The specification talks about the "response's body's transmitted" and the "response's body's length". What do these mean? I cannot find any definition of them in the standard. Is the "response's body's transmitted" the number of bytes that have been transmitted so far? Is the "response's body's length" the total length of the response in bytes? It would be good to define these terms in the specifications. 

If you look at those terms, they are links. They go to these locations:

- https://fetch.spec.whatwg.org/#concept-body-transmitted
- https://fetch.spec.whatwg.org/#concept-body-length

> (3) After reading the relevant part of the specification three times, I am still confused about what causes an "onprogress" event to be fired. In particular is a "progress" event named "progress" fired at regular intervals during transmission of a response, or whenever additional bytes arrive for a response, or what? I would find the first of these useful if my app was tracking the progress of a response for display to a human user. I would find the second of these useful if I was able to access partial responses and wanted to know when there is something new to access.  

The answer is essentially "both". When bytes come in, the UA checks if at least 50 ms have passed since the last progress event. If so, it will fire. So, if no bytes come in, there will be no progress event; if they come in more often than every 50 ms, not every occurrence will fire a progress event.

You can again get more fine-grained control over these things with Fetch + Streams. They operate on a "pull" model instead of a "push" model, so you call read() to get each chunk; the promise will only fulfill when new bytes have been read. You can then use this to track the progress for users.

Hope this helps! 

More information about the Help mailing list