it-swarm.com.de

Mit jquery ajax eine Binärdatei herunterladen

Ich versuche, Jquery Ajax zu verwenden, um eine binäre Audiodatei herunterzuladen. 

Normalerweise würde ich einfach einen Befehl wie diesen ausgeben:

 windows.location.href = 'http://marksdomain(dot)com/audioFile.wav' ;

In letzter Zeit hat unser Server jedoch zu lange auf eine Antwort gewartet, und ich erhalte eine böse Gateway-Zeitüberschreitungsmeldung.

Es wurde vorgeschlagen, dass ich stattdessen jquery-ajax verwende, was sinnvoll ist, da ich dann mehr Kontrolle über das Timeout hätte.

Hier ist der Code, mit dem ich bisher gespielt habe:

$.ajax(
    { url:   'http://marksdomain(dot)com/audioFile.wav'
    , timeout:      999999
    , dataType: 'binary'
    , processData:  false     // this one does not seem to do anything ?
    , success: function(result)  {
           console.log(result.length);
      }
    , error: function(result, errStatus, errorMessage){
            console.log(errStatus + ' -- ' + errorMessage);
      }

Wenn ich den "Datentyp" weglasse, wird die binäre Datei ungefähr dreimal größer als auf dem Server. Wenn ich jedoch den Datentyp gleich "binär" mache, gibt ajax einen Fehler aus:

"No conversion from text to binary"

In einigen früheren Beiträgen klingt es so, als könne Jquery-Ajax Binärdateien auf diese Weise nicht verarbeiten.

Ich habe Delivery.js entdeckt, das eigentlich ziemlich gut für das funktioniert, was ich versuche, aber ich würde lieber keine Knotenlösung verwenden, wenn dies möglich ist.

Irgendwelche Vorschläge?

13
edwardsmarkf

Verwenden Sie einfach XHR direkt. Dieses Beispiel stammt aus MDN :

var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";

oReq.onload = function(oEvent) {
  var arrayBuffer = oReq.response;

  // if you want to access the bytes:
  var byteArray = new Uint8Array(arrayBuffer);
  // ...

  // If you want to use the image in your DOM:
  var blob = new Blob(arrayBuffer, {type: "image/png"});
  var url = URL.createObjectURL(blob);
  someImageElement.src = url;

  // whatever...
};

oReq.send();
15
Brandon

Wenn Sie jQuery verwenden müssen, können Sie $.ajaxSetup() verwenden, um untergeordnete Einstellungen zu ändern.

Beispiel:

  // Set up AJAX settings for binary files:
  $.ajaxSetup({
    beforeSend: function (jqXHR, settings) {
      if (settings.dataType === 'binary') {
        settings.xhr().responseType = 'arraybuffer';
      }
    }
  })

  // Make the actual call:
  let result = await $.ajax({
    url: '/api/export/data',
    type: 'GET',
    contentType: 'application/json',
    dataType: 'binary',
    processData: false,
    headers: {
      token: localStorage.token,
    },
  });
1
K48

Sie können einen $ .ajax-Transport einrichten, um die Einstellungen wie hier erwähnt zu ändern: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/

// use this transport for "binary" data type

            $.ajaxTransport("+binary", function (options, originalOptions, jqXHR) {
                // check for conditions and support for blob / arraybuffer response type
                if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob))))) {
                    return {
                        // create new XMLHttpRequest
                        send: function (headers, callback) {
                            // setup all variables
                            var xhr = new XMLHttpRequest(),
                                url = options.url,
                                type = options.type,
                                async = options.async || true,
                                // blob or arraybuffer. Default is blob
                                dataType = options.responseType || "blob",
                                data = options.data || null,
                                username = options.username || null,
                                password = options.password || null;

                            xhr.addEventListener('load', function () {
                                var data = {};
                                data[options.dataType] = xhr.response;
                                // make callback and send data
                                callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
                            });

                            xhr.open(type, url, async, username, password);

                            // setup custom headers
                            for (var i in headers) {
                                xhr.setRequestHeader(i, headers[i]);
                            }

                            xhr.responseType = dataType;
                            xhr.send(data);
                        },
                        abort: function () {
                            jqXHR.abort();
                        }
                    };
                }
            });

und dann rufen Sie Ihren Ajax an:

 return $.ajax({
                    url: url,
                    method: 'GET',
                    dataType: 'binary',
                    processData: 'false',
                    responseType: 'arraybuffer',
                    headers: { 'X-Requested-With': 'XMLHttpRequest' }
                }).then(function (response) {
                    var data = new Uint8Array(response);
                    //do something with the data
                    return data;
                }, function (error) {
                    alertify.error('There was an error! Error:' + error.name + ':' + error.status)
                });
0
MattE