An Interest In:
Web News this Week
- March 20, 2024
- March 19, 2024
- March 18, 2024
- March 17, 2024
- March 16, 2024
- March 15, 2024
- March 14, 2024
Blob - Manipulando dados binrios em javascript
Essa semana, me deparei com uma situao nova enquanto desenvolvia uma extenso para google chrome com o Quasar Framework. Precisava guardar imagens e links na rea de transferncia (clipboard) para serem colados posteriormente num rich text editor. Mais especificamente, fotos do Instagram e um link para o perfil do autor.
Aps alguma pesquisa, vi que a soluo passava pela utilizao da classe Blob, da File Api.
TLDR;
A soluo que utilizei foi enviar pra rea de transferncia um Blob contendo o html formatado com as imagens e links. Para isso, o atributo src das imagens precisa conter data urls em vez de urls comuns.
Estes foram os passos utilizados:
- Obter a imagem e convert-la em data url:
const img = document.createElement('img');const response = await fetch('https://via.placeholder.com/350x150');// a response do fetch api j te devolve um blobconst blob = await response.blob(); // FileReader responsvel por gerar a data url em base64const reader = new FileReader();reader.readAsDataURL(blob);reader.onload = () => { img.src = reader.result;}// insere a imagem no body, apenas para exemplificar.document.body.appendChild(img);
- Transformar o html com a imagem em blob:
const htmlBlob = new Blob([document.body.innerHTML], {type: 'text/html'});
- Escrever o html na rea de transferncia via navigator api:
// note que pode ser necessrio solicitar permisso pra escrever na clipboardconst { state } = await navigator.permissions.query({ name: 'clipboard-write', });if(state === 'granted'){ await navigator.clipboard.write([ new ClipboardItem({ 'text/html': htmlBlob }) ]);}
O que um Blob?
Do ingls Binary Large Object, um blob representa um conjunto de dados binrios, normalmente associados a um MIME type (text/html; image/png; application/pdf etc.).
Podemos entender dado binrio, como o oposto de dado puramente textual (text/plain). No fim das contas, ambos so bits armazenados em memria. Porm, dados textuais precisam de um encoding para fazer sentido, a exemplo do UTF-8 ou do ANSI.
Os blobs, por si s, no permitem muita interao com seu conjunto de dados. Usualmente so utilizados junto com demais classes, como a URL, que permite a criao de urls apontando para um blob, til para usar em elementos como , que aceita uma url como seu source.
Anatomia do Blob:
- size
Tamanho total, em bytes. Note que, isso est mais para o length de um array do qu para o length de uma string. Isso porque existem caracteres que ocupam mais de um byte.
new Blob([""], {type: "text/plain"})// Blob {size: 2, type: 'text/plain'}new Blob(["a"], {type: "text/plain"})// Blob {size: 1, type: 'text/plain'}
- type
MIME type associado ao blob.
Blob URLs
Como dito acima, possvel gerar uma url referenciando o contedo de um blob. Isso pode ser feito de duas maneiras:
createObjectURL
A primeira atravs da classe URL, chamando o mtodo createObjectURL( blob )
. Esse mtodo retorna uma url no formato blob:https://site-de-origem-do-blob/identificador-do-blob
. Esse recurso fica armazenado numa rea especial do browser, enquanto o objeto que criou o blob existir. Por isso, no possvel acessar o contedo do blob se a aba onde ele foi gerado for fechada, por exemplo. Alm disso, necessrio chamar o revokeObjectURL( blobUrl )
to logo o recurso no seja mais necessrio. Caso contrrio, o blob no ser removido da memria pelo garbage collector enquanto o recurso que o criou existir. Isso um problema, a depender do tamanho/quantidade de blobs em memria.
// blob de stringconst blob = new Blob(["uma string qualquer"], {type: "text/plain"});const url = URL.createObjectURL(blob);console.log(blob);// Blob {size: 19, type: 'text/plain'}window.open(url, '_blank');// libera os bytes do blob reservados na memria pelo browserURL.revokeObjectURL(url);
// blob de um pngfetch('https://www.google.com.br/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png').then(response => response.blob()).then(blob => { console.log(blob); // Blob {size: 5969, type: 'image/png'} const url = URL.createObjectURL(blob); window.open(url, '_blank');})
readAsDataURL
A segunda forma de obter o blob como url gerar uma Data URL com seu contedo. Data URLs so como arquivos embutidos, representados por uma URL. So formadas por 4 partes: data:[<mediatype>][;base64],<data>
. data: o prefixo, assim como blob:; mediatype o MIME type do dado; base64 indica se os dados foram codificados em base64, que uma representao textual de dados binrios. possvel no usar base64, mas os dados tem que ser URL Encoded, no entanto, isso foge do nosso escopo no momento.
Para transformar um blob em Data URL, utilizamos a classe FileReader, e seu mtodo readAsDataURL.
// blob de um pngfetch('https://www.google.com.br/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png').then(response => response.blob()).then(blob => { console.log(blob); // Blob {size: 5969, type: 'image/png'} const fileReader = new FileReader(); fileReader.onload = () => { console.log(fileReader.result) // data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARAAAABcCAYAAACm5+q2AAAXGElEQVR4Ae1dC5QcVZm+OtOBwC6CwiqCCBIQkAWSqpqEk[...] } fileReader.readAsDataURL(blob);})
A url gerada pode ser atribuda ao src de qualquer elemento.
Download de Arquivos
Algumas restries de segurana se aplicam s data urls. Como exemplo, no possvel forar o download de arquivos nesse formato, nem abrir uma data url em uma nova aba. Os browsers tratam elas, de fato, como uma origin diferente. Tudo isso est relacionado ao bloqueio do chamado top level navigation. Dessa forma, a maneira mais conveniente de efetuar download programtico utilizar uma blob url.
fetch('https://via.placeholder.com/350x150').then(response => response.blob()).then(blob => { const link = document.createElement('a'); link.download = 'blob.png'; link.href = URL.createObjectURL(blob); link.click(); URL.revokeObjectURL(link.href);})
Consideraes Finais
Usar um ou outro mtodo de obteno de URL fica a critrio de cada aplicao. No meu caso, as imagens precisavam ser embutidas em outros documentos, em um editor fora do navegador. Dessa forma, no seria possvel usar uma blob url. Note, entretanto, que o processo de gerar a Data Url pode ser mais lento que apenas referenciar uma rea de memria, como faz o browser com a blob url. Alm disso, as especificaes de tamanho mximo do contedo contido numa data url variam de acordo ao navegador, partindo de cerca de 65535 caracteres at 2GB.
Para saber mais a respeito, recomendo a leitura de: https://javascript.info/blob
https://dev.to/kennethlum/understanding-what-a-blob-is-35ga
Original Link: https://dev.to/flacorlopes/blob-manipulando-dados-binarios-em-javascript-2nak
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To