Atualmente fazer download de arquivo(binário) por ajax, pode ser feito de algumas maneiras. O XMLHttpRequest nível 2 suporta o seguinte tipos de resposta : arraybuffer, blob, document, json e text.

Vou demonstrar como realizar download de arquivos binários utilizando os tipos de resposta arraybuffer e blob.

Conhecendo algumas propriedades do XMLHttpRequest

  • .responseType

    É a propriedade que define o tipo de resposta que a requisição irá devolver. Com isto o navegador saberá fazer o parse correto.
    Pode ter estes valores: arraybuffer, blob, document, json e text.

  • .response

    Após a requisição ter sido realizada com sucesso, o .response terá o conteudo "parseado" que pode ser DOMString, ArrayBuffer, Blob, Document ou JSON (deacordo com o responseType).

Fazendo o download de arquivos binários

Vou demonstrar o download de arquivos binários com ajax utilizando o conceito de Promises, se você ainda não sabe o que são Promises, por favor leia meu post JavaScript Promises.

  • Download utilizando ArrayBuffer

    ArrayBuffer é um tipo de Array de tamanho fixo contendo a representação binária(buffer de dados) de um arquivo, você não manipula ele diretamente, para maninular ele você precisa gerar um ArrayBufferView que pode ser através de um DataView ou de um Array tipado. ArrayBuffer são utilizados quando precisamos manipular os bytes de um arquivo, veja um exemplo utilizado pelo site Flickr: "Parsing Exif client-side using JavaScript"

    Para fazer download de um arquivo usando ArrayBuffer, basta setar o responseType com "arraybuffer":

    Após o download do arquivo o .response será um objeto ArrayBuffer, e você já pode utilizá-lo, por exemplo, você pode a partir de um ArrayBuffer de um arquivo de video, você pode criar um Blob para gerar uma URL que será o src de um elemento de video. Veja:

    Veja o exemplo rodando: exemplo


    Como eu já disse, é possível manipular os bytes do ArrayBuffer, através de um DataView ou de um Array tipado.
    Para manipular o ArrayBuffer byte a byte (8bits por vez) podemos utilizar o tipo Uint8Array, que retorna um array contendo o ArrayBuffer separado byte a byte, com tamanho de 8bits por posição.

    Veja esta ilustração:
    Meu próximo exemplo vou identificar o tipo de arquivo lendo os bytes de assinatura("Número Mágico") utilizando DataView (DataView.prototype.getUint8()).Cada arquivo tem uma assinatura hexadecimal conhecida como "Número Mágico", sendo assim possivel indentificar seu tipo, veja a lista de assinaturas dos arquivos.
    Exemplo:

    Veja o exemplo rodando: exemplo

  • Download utilizando Blob

    Blob é um objeto que representa um arquivo.Ele pode ser usado para fazer diversas operações nos arquivos.
    Para fazer download de um arquivo usando Blob, basta setar o responseType com "blob":

    No exemplo seguinte será realizado download de um video igual ao exemplo do ArrayBuffer, mas como nos já temos o blob que veio do .response, então fica mais simples:

    Veja o exemplo rodando: exemplo

Como demonstrado com ajax(XHR) podemos fazer download de arquivos binários e manipulá-los bit a bit.
Bom, por hoje é só.

Referências