Categorie
Javascript Programmazione

{JS} File API: I Blob

Chiarimento

E’ doveroso fare da subito un chiarimento; l’utilizzo dei blob è legato strettamente a file che non possiamo gestire liberamente con Javascript.
Questi file, sono chiamati file non-strutturati e si riferiscono a file di tipo video, immagini, software ecc.

I blob sono degli oggetti che rappresentano questi file come file-binari; si tratta di allocazioni che accettano dati binari e al contempo di riferimenti agli stessi.

Contenendo questi file all’interno di un blob, potremo manipolari liberamente ed effettuare diverse operazioni.
Le operazioni possibili sono molteplici come:
utilizzarli come risorse da inserire in elementi del DOM come <img>, <video> ecc., consentire il loro download ed il consequenziale trasferimento sul file system dell’utente, utilizzarli come contenuto di un buffer o ancora utilizzarli per memorizzare file nel loro complesso in un database.

Perché doverli utilizzare se possiamo utilizzare gli attributi “scr”/”href” direttamente negli elementi del DOM?
Il loro utilizzo è abbastanza specifico e dipende da particolari situazioni di sviluppo.

Senza l’utilizzo dei blob, avremmo potuto consentire lo scaricamento di file di un determinato tipo, un esempio su tutti sono i file con estensione .zip, sfruttando il comportamento di default del browser, ma in realtà, non abbiamo il pieno controllo; con i blob potremo consentire il download di qualunque file ed anche di gestire trasferimenti successivi all’inclusione di determinate informazioni da contenere nello stesso.

Lo stesso vale per i video, includendo una risorsa all’interno di un semplice tag <video> ci rifacciamo al comportamento di default che è una sorta di buffering preimpostato.

Ma precedentemente abbiamo visto come creare un buffer e come manipolarlo in maniera avanzata; con i blob, potremo inserire direttamente dei file all’interno di buffer per gestire la loro visualizzazione e/o il loro scaricamento.

In ultimo, ma non in ultimo, potremo utilizzarli per memorizzare dati-binari all’interno di database.
Qualunque database “mainstream” ha un tipo di campo blob per i dati binari.

Cosa sono i Blob?

Il termine BLOB, in inglese significa “massa priva di forma e di consistenza”.

In informatica un BLOB (acronimo per binary large object) è un oggetto che contengono tipi di dati di grandi dimensioni non strutturati.

Gli oggetti BLOB sono destinati alla memorizzazione di dati di grandi dimensioni in formato binario non direttamente interpretabile.

Parliamo di file come immagini grafiche, audio, programmi applicativi o altri oggetti multimediali che possono contenere fino a diversi gigabyte.

I BLOB sono quindi particolari oggetti, allocazioni, che contengono file non strutturati, file binari, di grandi dimensioni.

Dati strutturati e dati non strutturati

I dati strutturati sono quei dati organizzati in modo ordinato.

dati non strutturati non hanno un modello predefinito e non possono essere quindi organizzati in righe e colonne, non possono quindi essere conservati in modo schematico.

Tipi di file come: audio, video, immagini ecc tendono spesso ad essere molto grandi e occupano volumi molto superiori rispetto ai dati strutturati, motivo per il quale sono memorizzati sotto forma di oggetti binari, detti per l’appunto BLOB.

I database non sono in grado di leggere o comprendere il contenuto non strutturato dei BLOB, ma possono memorizzarlo nel suo complesso.

I BLOB possono anche essere utilizzati per memorizzare film o programmi televisivi in database in forma criptata, possono contenere file da passare ad un buffer ecc.

new Blob()

I BLOB possono rappresentare dati che non sono necessariamente in un formato nativo di JavaScript.

Possiamo creare oggetti blob mediante l’apposito costruttore:

var mioBlob = new Blob([Blobparts], options);
  • Il primo argomento del costruttore è un array che può conenere stringhe, BufferSource o altri Blob.
  • Il secondo argomento è opzionale ed è un oggetto che rappresenta il tipo di contenuto secondo lo standard MIME.

Facciamo subito degli esempi:

var primoBlob = new Blob(['<a href="http://www.cinquepuntozero.it">dev.logbook</a>'], {type: "text/html"});
var secondoBlob = new Blob(['Hello, world!'], {type: 'text/plain'});
var terzoBlob = new Blob(["file:///home/archivio.zip"], {type: "application/octet-stream"});
var quartoBlob = new Blob(["file:///home/video.mp4"], {type: "video/mp4"});
var quintoBlob = new Blob([JSON.stringify({ hello: "world" })], {type: "application/json"});

Come è possibile vedere è possibile convertire in BLOB praticamente qualunque cosa.

Note: quando indichiamo un file dovremo provvedere sempre con il preporre "file:" es. ["file:link"...] 

Tutti i BLOB creati condividono alcune proprietà:

ProprietàDescrizione
blob.sizerivela la dimensione in byte del contenuto
blob.typerivela il mime type del contenuto
var quintoBlob = new Blob([JSON.stringify({ hello: "world" })], {type: "application/json"});
quintoBlob.size;
//17
quintoBlob.type;
//application/json

Allo stesso modo abbia metodi condivisi tra tutti i BLOB:

Metodi Descrizione
blob.slice([byteStart], [byteEnd], [contentType])restituisce un nuovo oggetto Blob contenente i dati dell’intervallo di byte specificato
blob.stream()restituisce a 
ReadableStream che può essere utilizzato per leggere il contenuto del file Blob
blob.text()restituisce una promessa che se risolta restituisce i blob sotto forma di stringa UTF-8
blob.arrayBuffer()restituisce una promessa che se risolta contiene il contenuto sotto forma di dati binari

Usi comuni dei blob

I blob sono utilizzati per “trasportare” del contenuto non-strutturato, (racchiuso in un Blob Object) con il fine di depositarlo all’interno di elementi del DOM, all’interno di strutture per la gestione di buffer e per consentire il download degli sessi.

I BLOB sono molto utilizzati principalmente nell’industria del big data per raggruppare i dati “grezzi” raccolti dai visitatori di un sito web/app sotto forma di raccolte di dati (Blob Object) e memorizzati in database.

Codifica dei blob

Abbiamo visto cos’è un blob, come crearlo, abbiamo esaminato le proprietà disponibili ed i metodi per per la loro manipolazione, ma un oggetto blob così com’è, se non codificato, risulta inutile.

URL Object

Il metodo che stiamo per esaminare appartiene all’oggetto “URL”, che consente di creare url compositi:

new URL(url)
new URL(url, base)

Questo costruttore consente di specificare due argomenti: “url” il primo, rappresenta il percorso relativo; “base” opzionale rappresenta la radice.

var base = 'https://www.cinquepuntozero.it';
var percorsoUrl = new URL("/", base);     
// https://www.cinquepuntozero.it

var url = 'programmazione/javascript';
var secondoPercorsoUrl = new URL(url, base);
// https://www.cinquepuntozero.it/programmazione/javascript
URL.createObjectURL()

L’oggetto “URL” possiede un metodo accessibile dalla propria base molto utile per lavorare con i BLOB, il metodo URL.createObjectURL().

Questo accetta come argomenti: oggetti di tipo “File” e oggetti di tipo “Blob”.

var imageBlob = new Blob(["file:///home/img.bmp"], {type: 'image/bmp'});

var blobLink = URL.createObjectURL(quintoBlob);

Il metodo restituisce una stringa contenente un link all’oggetto blob utile per riferirsi al contenuto dello stesso.

blob:https://www.cinquepuntozero.it/1e67e00e-860d-40a5-89ae-6ab0cbee6273

Questa particolare stringa, memorizzata nella variabile “blobLink”, potrà essere utilizzata per essere inserita all’interno dell’attribuito “src” di un elemento del DOM di tipo image <img>

var immagine = document.getElementById('bellaimmagine');
immagine.src = blobLink;

Il ciclo di vita di un link creato mediante URL.createObjectURL() è legato al document; se la pagina viene ricaricato o cambiata, l’url viene distrutto.
Se invece lavoriamo su particolari strutture, pensiamo alle singlePage di Angual, sarà importante dovremo provvedere alla distruzione manuale attraverso il metodo URL.revokeObjectURL()

URL.revokeObjectURL(blobLink);

FileReader Object

Un alternativa a URL.createObjectURL è quella di convertire un blob in una stringa codificata in base 64, attraverso il metodo .readAsDataURL() dell’oggetto FileReader().

reader.readAsDataURL()

Il metodo reader.readAsDataURL() accetta come argomento un blob.

var imageBlob = new Blob(["file:///home/img.bmp"], {type: 'image/bmp'});

var reader = new FileReader();
reader.readAsDataURL(imageBlob);

reader.onload = function() {
  immagine.src = reader.result;
};

Abbiamo già visto in precedenza l’API FileReader e come funziona;
quello che cambia sostanzialmente è il formato di codifica del blob che in questo caso si presenterà cosi:

data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7
.readAsDataURL() per il download di file

Con i blob e l’oggetto FileReader possiamo consentire il download di file fruttando il metodo appena visto.

<a href="#" id="linkDownload" download="articolo.html">Scarica Immagine</a>

Il precedente snippet HTML rappresenta un link per consentire all’utente il download del file generato.

var imgBlob = new Blob(["file:https://www.cinquepuntozero.it/"], {type: "application/octet-stream"});

var linkDownload = document.getElementById('linkDownload');

var imageReader = new FileReader();

imageReader.onload = function(){
linkDownload.href = imageReader.readAsDataUrl(imgBlob);
}
Scarica Articolo

Il tipo di MIME “application/octet-stream" indica al browser che il file non deve essere interpretato ma deve essere scaricato sul file system dell’utente.

Nello snippet di codice HTML abbiamo utilizzato l’attributo “download=”articolo” questo ci consentirà di gestire il nome ed eventualmente l’estensione del file che sarà scaricato.

Se avessimo utilizzato URL.createObjectURL() questo non avrebbe funzionato:

var imgBlob = new Blob(["file:https://www.cinquepuntozero.it/"], {type: "application/octet-stream"});

var linkDownload = document.getElementById('linkDownload');
linkDownload.href = URL.createObjectURL(imgBlob);

}
reader.readAsArrayBuffer()

Se abbiamo bisogno di eseguire operazioni abbastanza semplici di buffering, possiamo utilizzare per convertire in buffer il metodo dell’oggetto sempre “FileReader”, “.readAsArrayBuffer()”

var reader = new FileReader();
reader.readAsArrayBuffer(imageBlob);

reader.onload = function(event) {
  arrayBuffer = fileReader.result;
};

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *