Ajax二进制响应

时间:2009-10-29 18:59:25

标签: javascript ajax prototypejs

嗨,我想知道是否还有在AJAX中流式传输二进制响应?这将是一个终极解决方案,否则我需要将二进制映像实现为文件,然后使用不同的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
  }
});

5 个答案:

答案 0 :(得分:21)

可能无法流式传输二进制数据,但您可以使用Ajax来检索二进制数据。

可以使用以下两种方法之一:Javascript Typed Arrays或XMLHttpResponse overrideMimeType hack。阅读一篇关于MDN的好文章 - 这些例子来自那里:Sending and Receiving Binary Data

Typed Array方法如下所示:

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);
IE中不支持

类型数组&lt; 10,Firefox&lt; 4,Chrome&lt; 7,Safari&lt; 5.1和Opera&lt; 11.6和mobile support is shaky but improving

第二种方法使用名为overrideMimeType的XMLHttpRequest方法来允许二进制数据通过未修改的方式传递。

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;

您将获得一个未解析的二进制字符串,您可以使用var byte = filestream.charCodeAt(x) & 0xff;来检索特定字节。

答案 1 :(得分:6)

这是对Tom Ashworth的回应的延伸(这有助于让我走上正确的轨道,面对我所面临的问题)。这允许你只获取文件流(FileStreamResult,如果你使用的是asp.net mvc)并将其设置为img src,这很酷。

var oReq = new XMLHttpRequest();
oReq.open("post", '/somelocation/getmypic', true );        
oReq.responseType = "blob";
oReq.onload = function ( oEvent )
{
    var blob = oReq.response;
    var imgSrc = URL.createObjectURL( blob );                        
    var $img = $( '<img/>', {                
        "alt": "test image",
        "src": imgSrc
    } ).appendTo( $( '#bb_theImageContainer' ) );
    window.URL.revokeObjectURL( imgSrc );
};
oReq.send( null );

基本思想是数据返回未被篡改,它被放置在blob中,然后在内存中为该对象创建一个url。请参阅herehere。注意支持的浏览器

答案 2 :(得分:4)

如果您想要动态生成图像,那么您可以做的就是:

<img src="http://myurl/myfile.php?id=3" />

然后您可以使用适当的mimetype发送数据。

如果你真的想要发送一个图像,那么你可能想要查看HTML5 canvas标签,但我不确定excanvas如何使用它,因为它是跨平台的。

您可以写入画布,但只使用img标签会更有效。

答案 3 :(得分:1)

你可以发送你想要的任何回复,无论是纯文本,HTML,图像......无论如何!你收到它后如何处理它取决于你。

但是......你不能将二进制图像分配给<IMG> src属性。你最好只是将URL返回到图像并指定它 - 好吧,说实话,有一些编码在SRC中嵌入图像,但它们不是跨浏览器所以你想要远离它们

答案 4 :(得分:1)

当您致电您的服务时,您应该要求 dataType: 'binary' 回复。然后,您可以使用 saveAs(FileSaver.js) 触发下载或 createObjectURL 在新窗口中打开。

但是,$.ajax 不允许您下载开箱即用的二进制内容,它会尝试从 UTF-8 解码您的二进制文件并破坏它。要么使用jQuery插件来解决这个问题jquery.binarytransport.js

示例:

$.ajax({
    type: "POST",
    url: $("form#data").attr("action"),
    data: formData,
    dataType: 'binary',     //--> using jquery.binarytransport.js
    success: function (response) {
        // Default response type is blob
        
        saveAs(response, "test.pdf"); //--> using FileSaver.js

        let fileURL = URL.createObjectURL(blob);
        window.open(fileURL);        // open file in new window
    }
});

好看! :)