So konvertieren Sie Blob in JavaScript in Datei

110

Ich muss ein Bild auf den NodeJS-Server in ein Verzeichnis hochladen. Ich benutze dafür das connect-busboyKnotenmodul.

Ich hatte das dataURLBild, das ich mit dem folgenden Code in Blob konvertiert habe:

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

Ich brauche eine Möglichkeit, den Blob in eine Datei zu konvertieren, um das Bild hochzuladen.

Könnte mir jemand dabei helfen?

überspringen
quelle
4
Dateien sind Blobs. Wenden Sie einfach die Meta-Eigenschaften an und los geht's.
Dandavis
1
Die Standardeinstellung für einen Blob beim Hochladen ist blob. Also extrahierte ich zuerst den Namen der Datei, die ich filenamebeschnitten hatte, und gab dann den gleichen Namen wie die zugeschnittene Datei, während ich sie auf den Server hochlud form.append("blob",blob, filename);.
Überspringen Sie den
@skip hat meine Antwort unten geholfen? Ist dies der Fall, markieren Sie es bitte als die richtige Antwort.
CBarr

Antworten:

147

Diese Funktion wandelt a Blobin a um Fileund funktioniert hervorragend für mich.

Vanille 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 (mit korrekter Eingabe)

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

Verwendung

var myBlob = new Blob();

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

var myFile = blobToFile(myBlob, "my-image.png");
CBarr
quelle
3
Ich denke, die Besetzung sollte zuerst stattfinden, damit Sie sie nicht anyin TypeScript verwenden müssen. Siehe dieses Beispiel.
Styfle
2
Dies funktioniert nicht für alle Zwecke. Durch Hinzufügen dieser "Datei" zu einem Ajax-Aufruf wird der Dateiname nicht korrekt festgelegt.
Jacob Poul Richardt
12
Dies ist keine gute Lösung, das produzierte Objekt ist immer noch ein Blob.
Czupe
4
Fügen Sie einfach b.__proto__ = File.prototypeund Ihre Lösung wird ein Traum , dass auch Tricks b instanceOf Filezutrue
manuelnaranjo
3
Dies sollte nicht die akzeptierte Antwort sein, stackoverflow.com/a/53205768/2557517 oder stackoverflow.com/a/31663645/2557517 .
Kira
203

Sie können den Dateikonstruktor verwenden:

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

Gemäß der w3-Spezifikation werden die im Blob enthaltenen Bytes an die Bytes für das neue Dateiobjekt angehängt und die Datei mit dem angegebenen Namen http://www.w3.org/TR/FileAPI/#dfn-file erstellt

Joshua P Nixon
quelle
2
Dies ist, wonach ich gesucht habe. Der einzige Unterschied ist, dass das erste Argument tatsächlich ein Array ist, also habe ich es verwendet als: var file = new File ([myBlob], "name");
Michaeldcooney
1
Ja. Ich suche auch nach dieser Lösung. Der Stamplay-Server kann den Dateinamen nicht vom Blob-Objekt abrufen. Also muss ich es wieder in eine Datei konvertieren. Aber Safari unterstützt keine Datei-API ... jetzt wieder auf 0 :(
Hugh Hou
4
Dateikonstruktoren funktionieren nicht zB in PhantomJS:TypeError: FileConstructor is not a constructor (evaluating 'new File([''], 'file.pdf', {'size': 1000, 'type': 'application/pdf'})')
bkimminich
7
Edge hat derzeit (2017-10-04) einen Fehler, der die Verwendung dieses Konstruktors verhindert. developer.microsoft.com/en-us/microsoft-edge/platform/issues/…
Rik Martins
7
Stellen Sie sicher, dass Sie den Dateityp hinzufügen, da dies sonst nicht ordnungsgemäß funktioniert. neue Datei ([myBlob], "name", {type: "image / jpeg",});
BernardA
34

Die Antwort von Joshua P Nixon ist richtig, aber ich musste auch das Datum der letzten Änderung festlegen. Also hier ist der Code.

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

1534584790000 ist ein Unix-Zeitstempel für " GMT: Samstag, 18. August 2018, 9:33:10 Uhr ".

mili
quelle
3
Punkte für nicht brechen instanceofwie die akzeptierte Antwort
Matt Jensen
14

Damit ich arbeiten konnte, musste ich den Typ explizit angeben, obwohl er im Blob enthalten ist:

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

Meine moderne Variante:

function blob2file(blobData) {
  const fd = new FormData();
  fd.set('a', blobData);
  return fd.get('a');
}
DAVID _
quelle
2
Um der resultierenden Datei einen Dateinamen hinzuzufügen, verwenden Sie:fd.set('a', blobData, 'filename')
joaoguerravieira
Es schlägt in einigen IOS-Geräten fehl, wennfd.set
Sing
Vielen Dank. Das funktioniert. Jetzt muss ich den Blob nicht mehr in eine Datei konvertieren.
xreyc_developer22
2

Verwendung saveAsim FileSaver.js- Github-Projekt.

FileSaver.jsImplementiert die saveAs()FileSaver-Oberfläche in Browsern, die sie nicht nativ unterstützen.

Moslemischer Shahsavan
quelle