使用jquery ajax下载二进制文件

edw*_*rkf 23 javascript ajax jquery

我试图使用jquery ajax下载二进制音频文件.

通常我会发出这样的命令:

 windows.location.href = 'http://marksdomain(dot)com/audioFile.wav' ;
Run Code Online (Sandbox Code Playgroud)

但是,最近我们的服务器等待响应的时间太长了,我得到一个讨厌的网关超时消息.

有人建议我使用jquery-ajax,这是有道理的,因为那时我会更多地控制超时.

这是我到目前为止玩过的代码:

$.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);
    }
};
Run Code Online (Sandbox Code Playgroud)

当我省略"dataType"时,二进制文件的大小比服务器上实际大三倍.但是,当我使dataType等于"binary"时,ajax会抛出一个错误:

"No conversion from text to binary"
Run Code Online (Sandbox Code Playgroud)

从一些早期的帖子中,听起来好像jquery-ajax无法以这种方式处理二进制文件.

我确实发现了Delivery.js,它实际上对我正在尝试的东西非常有效,但我宁愿不使用节点解决方案.

有什么建议?

Bra*_*don 26

只需直接使用XHR即可.此示例来自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();
Run Code Online (Sandbox Code Playgroud)

  • 但是现在您可以访问请求对象并且可以在发送请求之前调整“超时”,我认为这是您的目标吗? (2认同)

小智 5

如果必须使用jQuery,可以使用$.ajaxSetup()修改低级设置。

例子:

  // 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,
    },
  });
Run Code Online (Sandbox Code Playgroud)

  • 抱歉:仍然失败,“没有从文本到二进制的转换”。 (5认同)

Mat*_*ttE 5

您可以按如下所述设置$ .ajax传输来修改设置: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();
                        }
                    };
                }
            });
Run Code Online (Sandbox Code Playgroud)

然后打电话给ajax:

 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)
                });
Run Code Online (Sandbox Code Playgroud)