Come convertire BLOB in file in JavaScript


111

Devo caricare un'immagine sul server NodeJS in una directory. Sto usando il connect-busboymodulo del nodo per questo.

Avevo dataURLl'immagine dell'immagine che ho convertito in blob utilizzando il codice seguente:

dataURLToBlob: function(dataURL) {
    var BASE64_MARKER = ';base64,';
    if (dataURL.indexOf(BASE64_MARKER) == -1) {
        var parts = dataURL.split(',');
        var contentType = parts[0].split(':')[1];
        var raw = decodeURIComponent(parts[1]);
        return new Blob([raw], {type: contentType});
    }
    var parts = dataURL.split(BASE64_MARKER);
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;
    var uInt8Array = new Uint8Array(rawLength);
    for (var i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {type: contentType});
}

Ho bisogno di un modo per convertire il BLOB in un file per caricare l'immagine.

Qualcuno potrebbe aiutarmi con questo?


4
I file sono BLOB, basta aggiungere le meta proprietà e sei a posto.
dandavis

1
L'impostazione predefinita per un BLOB durante il caricamento è blob. Quindi, ho prima estratto il nome del file che stavo ritagliando e poi ho dato lo stesso in filenamemodo che il file ritagliato mentre lo caricavo sul server form.append("blob",blob, filename);.
salta il

@skip ha aiutato la mia risposta qui sotto? Se è così, contrassegnalo come risposta corretta.
CBarr

Risposte:


149

Questa funzione converte a Blobin a Filee funziona benissimo per me.

Vanilla JavaScript

function blobToFile(theBlob, fileName){
    //A Blob() is almost a File() - it's just missing the two properties below which we will add
    theBlob.lastModifiedDate = new Date();
    theBlob.name = fileName;
    return theBlob;
}

TypeScript (con la corretta digitazione)

public blobToFile = (theBlob: Blob, fileName:string): File => {
    var b: any = theBlob;
    //A Blob() is almost a File() - it's just missing the two properties below which we will add
    b.lastModifiedDate = new Date();
    b.name = fileName;

    //Cast to a File() type
    return <File>theBlob;
}

uso

var myBlob = new Blob();

//do stuff here to give the blob some data...

var myFile = blobToFile(myBlob, "my-image.png");

3
Penso che il cast dovrebbe avvenire prima, quindi non è necessario utilizzarlo anyin TypeScript. Vedi questo esempio.
stile

2
Questo non funziona per tutti gli scopi. L'aggiunta di questo "File" a una chiamata ajax non imposterà correttamente il nome del file.
Jacob Poul Richardt

12
Questa non è una buona soluzione, l'oggetto prodotto è ancora un blob.
czupe

4
Basta aggiungere b.__proto__ = File.prototype, e la soluzione diventa un sogno che inganna anche b instanceOf Fileatrue
manuelnaranjo

3
Questa non dovrebbe essere la risposta accettata, dovrebbe esserlo stackoverflow.com/a/53205768/2557517 o stackoverflow.com/a/31663645/2557517 .
Kira

204

Puoi usare il costruttore di file:

var file = new File([myBlob], "name");

Secondo la specifica w3, questo aggiungerà i byte che il blob contiene ai byte per il nuovo oggetto File e creerà il file con il nome specificato http://www.w3.org/TR/FileAPI/#dfn-file


2
Questo è quello che stavo cercando, l'unica differenza è che il primo argomento è in realtà un array, quindi l'ho usato come: var file = new File ([myBlob], "name");
Michaeldcooney

1
Sì. Sto cercando anche questa soluzione. Il server Stamplay non può ottenere il nome del file dall'oggetto BLOB. Quindi ho bisogno di riconvertirlo in file. Ma Safari non supporta l'API dei file ... torna a 0 ora :(
Hugh Hou

4
I costruttori di file non funzionano, ad esempio, in PhantomJS:TypeError: FileConstructor is not a constructor (evaluating 'new File([''], 'file.pdf', {'size': 1000, 'type': 'application/pdf'})')
bkimminich

7
Edge ha attualmente (2017-10-04) un bug che impedisce l'utilizzo di questo costruttore. developer.microsoft.com/en-us/microsoft-edge/platform/issues/…
Rik Martins

8
Assicurati di aggiungere il tipo di file, altrimenti non funzionerà correttamente. nuovo file ([myBlob], "name", {type: "image / jpeg",});
BernardA

34

La risposta di Joshua P Nixon è corretta ma ho dovuto impostare anche la data dell'ultima modifica. quindi ecco il codice.

var file = new File([blob], "file_name", {lastModified: 1534584790000});

1534584790000 è un timestamp unix per " GMT: sabato 18 agosto 2018 9:33:10 "


3
Punti per non rompere instanceofcome la risposta accettata
Matt Jensen

15

Per poter funzionare ho dovuto fornire esplicitamente il tipo sebbene sia contenuto nel BLOB in questo modo:

const file = new File([blob], 'untitled', { type: blob.type })

13

La mia variante moderna :

function blob2file(blobData) {
  const fd = new FormData();
  fd.set('a', blobData);
  return fd.get('a');
}

2
Per aggiungere un nome file al file risultante, utilizzare:fd.set('a', blobData, 'filename')
joaoguerravieira

Non funziona in alcuni dispositivi IOS quandofd.set
Canta

Grazie. funziona, ora non devo convertire blob in file.
xreyc_developer22

2

Utilizzare saveAsnel progetto github FileSaver.js .

FileSaver.jsimplementa l' saveAs()interfaccia FileSaver nei browser che non la supportano in modo nativo.


2

Dattiloscritto

public blobToFile = (theBlob: Blob, fileName:string): File => {       
    return new File([theBlob], fileName, { lastModified: new Date().getTime(), type: theBlob.type })
}

Javascript

function blobToFile(theBlob, fileName){       
    return new File([theBlob], fileName, { lastModified: new Date().getTime(), type: theBlob.type })
}

Produzione

immagine dello schermo

File {name: "fileName", lastModified: 1597081051454, lastModifiedDate: Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time), webkitRelativePath: "", size: 601887, …}
lastModified: 1597081051454
lastModifiedDate: Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time) {}
name: "fileName"
size: 601887
type: "image/png"
webkitRelativePath: ""
__proto__: File
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.