Does jQuery $.ajax or $.load allow for responseType arrayBuffer?
Asked Answered
A

6

28

I'm getting started with the Web Audio API and just wondering if it's possible to use jQuery's $.ajax or $.load functions to make the XMLHttpRequest that receives the audio data. Do $.ajax or $.load support responseType=arrayBuffer?

EDIT:

Ok, so here's what I have so far:

function loadAudio() {
    $.ajax({
            url: sourceUrl
        }).done(function(response){
            return response;
        })
    }

but I need to return an ArrayBuffer. So how do I convert the response into an ArrayBuffer?

Auberge answered 12/9, 2012 at 19:1 Comment(0)
B
23

About your question, it seems jQuery does not support it yet. Before using it as I suggested below, consider checking if the feature is available.

With XHTMLRequest, you can trick your server and receive a binary string representing the bytes you want from the server. It works perfectly.

var xhr = new XMLHttpRequest();
xhr.open('GET', '/your/audio/file.wav', true);

// Here is the hack
xhr.overrideMimeType('text/plain; charset=x-user-defined');

xhr.onreadystatechange = function(event) {
  if ( this.readyState == 4 && this.status == 200 ) {
    var binaryString = this.responseText;

    for (var i = 0, len = binaryString.length; i < len; ++i) {
      var c = binaryString.charCodeAt(i);
      var byte = c & 0xff; //it gives you the byte at i
      //Do your cool stuff...

    }
  }
};

xhr.send();

It works, it's common... but... it is still a hack.

With XHTML Request Level 2, you can specify the responseType as 'arraybuffer' and receive the ArrayBuffer actually. It is much nicer. The problem is to check if your browser support this feature.

var xhr = new XMLHttpRequest();
xhr.open('GET', '/your/audio/file.wav', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
  if (this.status == 200) {
    //Do your stuff here
  }
};

xhr.send();

Hope I helped.

Borne answered 22/5, 2013 at 17:7 Comment(0)
G
8

I used Dylan's answer and it worked, but the resulting $.ajax request is not a full Promise anymore (I couldn't combine it with Promise.all anymore). Instead, I achieved the same by using the xhrFields setting from the documentation.

$.ajax({
    url: url,
    method: 'GET',
    xhrFields: { responseType: 'arraybuffer'}
})
Glosso answered 31/1, 2022 at 15:19 Comment(0)
I
6

Actually there is an easier way to do this using jQuery and the native XMLHttpRequest without having to use only the XMLHttpRequest or having to use a plugin, so you can still code in jQuery style/syntax. One of the options for $.ajax() is xhr, which the jQuery documentation describes as (emphasis mine):

xhr (default: ActiveXObject when available (IE), the XMLHttpRequest otherwise)

Type: Function()

Callback for creating the XMLHttpRequest object. Defaults to the ActiveXObject when available (IE), the XMLHttpRequest otherwise. Override to provide your own implementation for XMLHttpRequest or enhancements to the factory.

So, in order to get an ArrayBuffer as a response to a $.ajax() request, all you have to do is:

var xhrOverride = new XMLHttpRequest();
xhrOverride.responseType = 'arraybuffer';

$.ajax({
    url: '/url/of/your/binary/data',
    method: 'GET',
    xhr: function() {
        return xhrOverride;
    }
}).then(function (responseData) {

    // responseData is an ArrayBuffer!

});
Interlanguage answered 6/3, 2020 at 19:51 Comment(1)
This doesn't always work -- it breaks when the file is of a type like .json, .xml, .html, etc. To fix it, I found you can set options dataType: "x-binary", and converters: {'* x-binary'(value) {return value}} to bypass jQuery's response data filtering.Written
S
0

i fetched the data from server as string(which is base64 encoded to string) using ajax get json and then on client side i decoded it to base64 and then to array buffer.

Sample code

function solution1(base64Data) {

var arrBuffer = base64ToArrayBuffer(base64Data);

// It is necessary to create a new blob object with mime-type explicitly set
// otherwise only Chrome works like it should
var newBlob = new Blob([arrBuffer], { type: "application/pdf" });

// IE doesn't allow using a blob object directly as link href
// instead it is necessary to use msSaveOrOpenBlob
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(newBlob);
    return;
}

// For other browsers: 
// Create a link pointing to the ObjectURL containing the blob.
var data = window.URL.createObjectURL(newBlob);

var link = document.createElement('a');
document.body.appendChild(link); //required in FF, optional for Chrome
link.href = data;
link.download = "file.pdf";
link.click();
window.URL.revokeObjectURL(data);
link.remove();

}

function base64ToArrayBuffer(data) {
var binaryString = window.atob(data);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
    var ascii = binaryString.charCodeAt(i);
    bytes[i] = ascii;
}
return bytes;

};

Suzannasuzanne answered 14/8, 2017 at 8:1 Comment(1)
If this fails for anyone, try #33902799Steakhouse
J
0

There is a simple jQuery extension for this: https://github.com/vobruba-martin/jquery.ajax.arraybuffer

$.get("https://www.website.com/image.png", function(data)
{
    console.log("received data", data);
}, "arraybuffer");
Janis answered 16/1, 2020 at 8:39 Comment(0)
P
0

Yes, it does support responseType = 'arrayBuffer'.

var settings = {
type : 'GET',
xhrFields = {responseType: 'arrayBuffer'},
dataType = 'binary',
success: function(response) { console.log('Success'); },
error: function(xhr, status, error) { console.log('Error:', error); } };

const binaryString = $.ajax(url, [,settings]).done(function(response) { return response; });

const arrayBuffer_array = convert_binaryString_to_arraybuffer(binaryString);

function convert_binaryString_to_arraybuffer(binaryString) {
     var character_array = binaryString.split('');
     console.log("character_array: ", character_array);
        
     // Map each binary string character as an ASCII number
     var byteArray = character_array.map((character) => { return character.charCodeAt(0); });
     console.log("byteArray: ", byteArray);

     return new Uint8Array(byteArray);
}
Polled answered 31/7 at 11:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.