Usando FileReader
o readAsDataURL()
, posso transformar dados arbitrários em uma URL de dados. Existe uma maneira de converter um URL de dados de volta em uma Blob
instância usando apis do navegador embutido?
Usando FileReader
o readAsDataURL()
, posso transformar dados arbitrários em uma URL de dados. Existe uma maneira de converter um URL de dados de volta em uma Blob
instância usando apis do navegador embutido?
Respostas:
O usuário Matt propôs o seguinte código há um ano ( Como converter dataURL em objeto de arquivo em javascript? ) Que pode ajudá-lo
EDIT: Como alguns comentadores relataram, BlobBuilder foi preterido há algum tempo. Este é o código atualizado:
function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
// create a view into the buffer
var ia = new Uint8Array(ab);
// set the bytes of the buffer to the correct values
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var blob = new Blob([ab], {type: mimeString});
return blob;
}
Como o método @Adria, mas com Fetch api e apenas menor [ caniuse? ]
Não é preciso pensar no tipo MIME, já que o tipo de resposta do blob funciona fora da caixa
Aviso: pode violar a Política de Segurança de Conteúdo (CSP)
... se você usar essas coisas
var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
fetch(url)
.then(res => res.blob())
.then(blob => console.log(blob))
Não pense que você poderia fazer isso menor do que este sem usar lib's
const blob = await (await fetch(url)).blob();
fetch
é a força de ter uma API assíncrona.
dataURItoBlob : function(dataURI, dataTYPE) {
var binary = atob(dataURI.split(',')[1]), array = [];
for(var i = 0; i < binary.length; i++) array.push(binary.charCodeAt(i));
return new Blob([new Uint8Array(array)], {type: dataTYPE});
}
input dataURI é o URL de dados e dataTYPE é o tipo de arquivo e o objeto blob de saída
dataTYPE
está embutido dataURI
e, portanto, deve ser analisado como na primeira resposta.
Método baseado em XHR.
function dataURLtoBlob( dataUrl, callback )
{
var req = new XMLHttpRequest;
req.open( 'GET', dataUrl );
req.responseType = 'arraybuffer'; // Can't use blob directly because of https://crbug.com/412752
req.onload = function fileLoaded(e)
{
// If you require the blob to have correct mime type
var mime = this.getResponseHeader('content-type');
callback( new Blob([this.response], {type:mime}) );
};
req.send();
}
dataURLtoBlob( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==', function( blob )
{
console.log( blob );
});
Em navegadores modernos, pode-se usar o único liner sugerido por Christian d'Heureuse em um comentário:
const blob = await (await fetch(dataURI)).blob();
experimentar:
function dataURItoBlob(dataURI) {
if(typeof dataURI !== 'string'){
throw new Error('Invalid argument: dataURI must be a string');
}
dataURI = dataURI.split(',');
var type = dataURI[0].split(':')[1].split(';')[0],
byteString = atob(dataURI[1]),
byteStringLength = byteString.length,
arrayBuffer = new ArrayBuffer(byteStringLength),
intArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteStringLength; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {
type: type
});
}
function dataURLtoBlob( dataUrl, callback )
{
var req = new XMLHttpRequest;
req.open( 'GET', dataUrl );
req.responseType = 'blob';
req.onload = function fileLoaded(e)
{
callback(this.response);
};
req.send();
}
var dataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
dataURLtoBlob(dataURI , function( blob )
{
console.log( blob );
});
Use meu código para converter dataURI em blob. É mais simples e mais limpo do que outros.
function dataURItoBlob(dataURI) {
var arr = dataURI.split(','), mime = arr[0].match(/:(.*?);/)[1];
return new Blob([atob(arr[1])], {type:mime});
}
Como nenhuma dessas respostas oferece suporte a dataURLs de base64 e não-base64, aqui está uma que o faz com base na resposta excluída de vuamitom:
// from /programming/37135417/download-canvas-as-png-in-fabric-js-giving-network-error/
var dataURLtoBlob = exports.dataURLtoBlob = function(dataurl) {
var parts = dataurl.split(','), mime = parts[0].match(/:(.*?);/)[1]
if(parts[0].indexOf('base64') !== -1) {
var bstr = atob(parts[1]), n = bstr.length, u8arr = new Uint8Array(n)
while(n--){
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], {type:mime})
} else {
var raw = decodeURIComponent(parts[1])
return new Blob([raw], {type: mime})
}
}
Observação: não tenho certeza se há outros tipos mime dataURL que podem ter que ser tratados de forma diferente. Mas, por favor, deixe-me saber se você descobrir! É possível que dataURLs possam simplesmente ter qualquer formato que desejem e, nesse caso, caberia a você encontrar o código certo para seu caso de uso específico.
usar
FileReader.readAsArrayBuffer(Blob|File)
ao invés de
FileReader.readAsDataURL(Blob|File)
ArrayBuffer
caminho alternativo não funcionará.