【问题标题】:Does jQuery $.ajax or $.load allow for responseType arrayBuffer?jQuery $.ajax 或 $.load 是否允许 responseType arrayBuffer?
【发布时间】:2022-01-31 23:19:30
【问题描述】:

我开始使用 Web Audio API,只是想知道是否可以使用 jQuery 的 $.ajax 或 $.load 函数来生成接收音频数据的 XMLHttpRequest。 $.ajax 或 $.load 是否支持 responseType=arrayBuffer?

编辑:

好的,这就是我目前所拥有的:

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

但我需要返回一个 ArrayBuffer。那么如何将响应转换为 ArrayBuffer 呢?

【问题讨论】:

    标签: jquery ajax xmlhttprequest


    【解决方案1】:

    关于你的问题,jQuery 似乎还不支持它。在按照我下面的建议使用它之前,请考虑检查该功能是否可用。

    使用 XHTMLRequest,您可以欺骗您的服务器并从服务器接收表示您想要的字节的二进制字符串。效果很好。

    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();
    

    它有效,它很常见......但是......它仍然是一个黑客。

    使用 XHTML 请求级别 2,您可以将 responseType 指定为 'arraybuffer' 并实际接收 ArrayBuffer。它要好得多。问题是检查您的浏览器是否支持此功能。

    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();
    

    希望我能帮上忙。

    【讨论】:

      【解决方案2】:

      实际上有一种更简单的方法可以使用 jQuery 和本机 XMLHttpRequest 来完成此操作,而不必使用 XMLHttpRequest 或不必使用插件,因此您仍然可以在 jQuery 中编码样式/语法。 $.ajax() 的选项之一是 xhrjQuery documentation 将其描述为(强调我的):

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

      类型:函数()

      用于创建 XMLHttpRequest 对象的回调。默认为 ActiveXObject 可用时 (IE),否则为 XMLHttpRequest。 重写以提供您自己的 XMLHttpRequest 实现 或 对工厂的增强。

      因此,为了获得ArrayBuffer 作为对$.ajax() 请求的响应,您所要做的就是:

      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!
      
      });
      

      【讨论】:

      • 这并不总是有效 - 当文件是 .json、.xml、.html 等类型时它会中断。要修复它,我发现您可以设置选项 dataType: "x-binary" , 和 converters: {'* x-binary'(value) {return value}} 绕过 jQuery 的响应数据过滤。
      【解决方案3】:

      我使用了 Dylan's answer 并且它工作了,但是生成的 $.ajax 请求不再是完整的 Promise(我不能再将它与 Promise.all 结合使用)。相反,我通过使用文档中的 xhrFields 设置实现了同样的效果。

      $.ajax({
          url: url,
          method: 'GET',
          xhrFields: { responseType: 'arraybuffer'}
      })
      

      【讨论】:

        【解决方案4】:

        我使用 ajax get json 从服务器获取数据作为字符串(base64 编码为字符串),然后在客户端我将其解码为 base64,然后解码到数组缓冲区。

        示例代码

        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;
        

        };

        【讨论】:

        【解决方案5】:

        有一个简单的 jQuery 扩展: https://github.com/vobruba-martin/jquery.ajax.arraybuffer

        $.get("https://www.website.com/image.png", function(data)
        {
            console.log("received data", data);
        }, "arraybuffer");
        

        【讨论】:

          猜你喜欢
          • 2018-04-29
          • 2019-01-18
          • 1970-01-01
          • 2011-06-10
          • 2020-07-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多