Comment convertir Blob en fichier en JavaScript

111

J'ai besoin de télécharger une image sur le serveur NodeJS dans un répertoire. J'utilise le connect-busboymodule de nœud pour cela.

J'ai eu le dataURLde l'image que j'ai convertie en blob en utilisant le code suivant:

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});
}

J'ai besoin d'un moyen de convertir l'objet blob en fichier pour télécharger l'image.

Quelqu'un pourrait-il m'aider?

sauter
la source
4
Les fichiers sont des blobs, il suffit de clouer les méta propriétés et vous êtes prêt à partir.
dandavis
1
La valeur par défaut pour un objet blob lors de son téléchargement est blob. Donc, j'ai d'abord extrait le nom du fichier que j'étais filenameen train de recadrer, puis j'ai donné le même fichier que le fichier recadré tout en le téléchargeant sur le serveur en faisant form.append("blob",blob, filename);.
sautez
@skip ma réponse ci-dessous vous a-t-elle aidé? Si oui, veuillez le marquer comme la bonne réponse.
CBarr

Réponses:

150

Cette fonction convertit un Bloben un Fileet cela fonctionne très bien pour moi.

JavaScript vanille

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 (avec des typages appropriés)

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;
}

Usage

var myBlob = new Blob();

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

var myFile = blobToFile(myBlob, "my-image.png");
CBarr
la source
3
Je pense que le casting devrait avoir lieu en premier, vous n'avez donc pas besoin de l'utiliser anydans TypeScript. Voyez cet exemple.
styfle
2
Cela ne fonctionne pas à toutes fins. L'ajout de ce "fichier" à un appel ajax ne définira pas correctement le nom de fichier.
Jacob Poul Richardt
12
Ce n'est pas une bonne solution, l'objet produit toujours un blob.
czupe
4
Il suffit d' ajouter b.__proto__ = File.prototype, et votre solution devient un rêve que même des tours b instanceOf Fileàtrue
manuelnaranjo
3
Cela ne devrait pas être la réponse acceptée, stackoverflow.com/a/53205768/2557517 ou stackoverflow.com/a/31663645/2557517 devrait l'être.
Kira
204

Vous pouvez utiliser le constructeur de fichier:

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

Conformément à la spécification w3, cela ajoutera les octets que le blob contient aux octets du nouvel objet File et créera le fichier avec le nom spécifié http://www.w3.org/TR/FileAPI/#dfn-file

Joshua P Nixon
la source
2
C'est ce que je cherchais, la seule différence est que le premier argument est en fait un tableau donc je l'ai utilisé comme: var file = new File ([myBlob], "name");
Michaeldcooney
1
Oui. Je recherche aussi cette solution. Le serveur Stamplay ne peut pas obtenir le nom de fichier de l'objet blob. J'ai donc besoin de le reconvertir en fichier. Mais Safari ne prend pas en charge l'API de fichier ... retour à 0 maintenant :(
Hugh Hou
4
Les constructeurs de fichiers ne fonctionnent pas par exemple dans PhantomJS:TypeError: FileConstructor is not a constructor (evaluating 'new File([''], 'file.pdf', {'size': 1000, 'type': 'application/pdf'})')
bkimminich
7
Edge a actuellement (2017-10-04) un bogue qui empêche l'utilisation de ce constructeur. developer.microsoft.com/en-us/microsoft-edge/platform/issues/…
Rik Martins
8
Assurez-vous d'ajouter un type de fichier, sinon cela ne fonctionnera pas correctement. nouveau fichier ([myBlob], "nom", {type: "image / jpeg",});
BernardA
34

La réponse de Joshua P Nixon est correcte mais je devais aussi fixer la date de la dernière modification. voici donc le code.

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

1534584790000 est un horodatage unix pour " GMT: samedi 18 août 2018 9:33:10 AM "

mili
la source
3
Points pour ne pas casser instanceofcomme la réponse acceptée
Matt Jensen
15

Pour que je travaille, je devais fournir explicitement le type bien qu'il soit contenu dans le blob en le faisant:

const file = new File([blob], 'untitled', { type: blob.type })
Alexandre Daubricourt
la source
14

Ma variante moderne :

function blob2file(blobData) {
  const fd = new FormData();
  fd.set('a', blobData);
  return fd.get('a');
}
DAVID _
la source
2
Pour ajouter un nom de fichier au fichier résultant, utilisez:fd.set('a', blobData, 'filename')
joaoguerravieira
Il échoue dans certains appareils IOS quandfd.set
Chantez
Merci. cela fonctionne, maintenant je n'ai pas à convertir le blob en fichier.
xreyc_developer22
2

À utiliser saveAssur le projet github FileSaver.js .

FileSaver.jsimplémente l' saveAs()interface FileSaver dans les navigateurs qui ne la prennent pas en charge de manière native.

Musulman Shahsavan
la source
2

Manuscrit

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 })
}

Production

capture d'écran

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
Hossam EL-Kashef
la source