Sunday, October 25, 2020

Streaming data with XHR

In some cases an application may need or want to process a stream of data incrementally: upload the data to the server as it becomes available on the client, or process the downloaded data as it arrives from the server. Unfortunately, while this is an important use case, today there is no simple, efficient, cross-browser API for XHR streaming:


The send method expects the full payload in case of uploads.


The response, responseText, and responseXML attributes are not designed for streaming.


Streaming has never been an official use case within the official XHR specification. As a result, short of manually splitting an upload into smaller, individual XHRs, there is no API for streaming data from client to server. Similarly, while the XHR2 specification does provide some ability to read a partial response from the server, the implementation is inefficient and very limited. That’s the bad news.



The good news is that there is hope on the horizon! Lack of streaming support as a first-class use case for XHR is a well-recognized limitation, and there is work in progress to address the problem:


Web applications should have the ability to acquire and manipulate data in a wide variety of forms, including as a sequence of data made available over time. This specification defines the basic representation for Streams, errors raised by Streams, and programmatic ways to read and create Streams.



The combination of XHR and Streams API will enable efficient XHR streaming in the browser. However, the Streams API is still under active discussion, and is not yet available in any browser. So, with that, we’re stuck, right? Well, not quite. As we noted earlier, streaming uploads with XHR is not an option, but we do have limited support for streaming downloads with XHR:



var xhr = new XMLHttpRequest();

xhr.open('GET', '/stream');

xhr.seenBytes = 0;


xhr.onreadystatechange = function() { 

  if(xhr.readyState > 2) {

    var newData = xhr.responseText.substr(xhr.seenBytes); 

    // process newData


    xhr.seenBytes = xhr.responseText.length; 

  }

};


xhr.send();



Subscribe to state and progress notifications

Extract new data from partial response

Update processed byte offset




References:

https://hpbn.co/xmlhttprequest/

No comments:

Post a Comment