Search code examples
javascriptajaxprototypejs

Ajax Binary Response


Hi I'm wondering if there's anyway to stream a binary response in AJAX? This would be an ultimate solution otherwise I would need to realize the binary image to a file then stream that file to the user with a different URL.

new Ajax.Request('/viewImage?id=123', {
  // request returns a binary image inputstream
  onSuccess: function(transport) {
      // text example
      // alert(transport.responseText)

      // QUESTION: is there a streaming binary response?
      $('imgElem').src = transport.responseBinary;
  },
  onFailure: function(transport) {
      // handle failure
  }
});

Solution

  • It might not be possible to stream binary data, but you can use Ajax to retrieve binary data.

    This is possible using one of two methods: Javascript Typed Arrays or an XMLHttpResponse overrideMimeType hack. Have a read of a good article on MDN – these examples are taken from there: Sending and Receiving Binary Data

    The Typed Array method looks like this:

    var oReq = new XMLHttpRequest();
    oReq.open("GET", "/myfile.png", true);
    oReq.responseType = "arraybuffer";
    
    oReq.onload = function (oEvent) {
      var arrayBuffer = oReq.response; // Note: not oReq.responseText
      if (arrayBuffer) {
        var byteArray = new Uint8Array(arrayBuffer);
        for (var i = 0; i < byteArray.byteLength; i++) {
          // do something with each byte in the array
        }
      }
    };
    
    oReq.send(null);
    

    Typed Arrays are not supported in IE < 10, Firefox < 4, Chrome < 7, Safari < 5.1 and Opera < 11.6, and mobile support is shaky but improving.

    The second method uses an XMLHttpRequest method called overrideMimeType to allow the binary data to be passed through unmodified.

    var req = new XMLHttpRequest();
    req.open('GET', '/myfile.png', false);
    // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
    req.overrideMimeType('text\/plain; charset=x-user-defined');
    req.send(null);
    if (req.status != 200) return '';
    // do stuff with req.responseText;
    

    You get an unparsed binary string, upon which you can use var byte = filestream.charCodeAt(x) & 0xff; to retrieve a specific byte.