Wie kann man einem als FormData hochgeladenen Blob einen Dateinamen geben?


76

Ich lade derzeit Bilder hoch, die mit dem folgenden Code aus der Zwischenablage eingefügt wurden:

// Turns out getAsFile will return a blob, not a file
var blob = event.clipboardData.items[0].getAsFile(), 
    form = new FormData(),
    request = new XMLHttpRequest();
form.append("blob",blob);
request.open(
            "POST",
            "/upload",
            true
        );
request.send(form);

Es stellt sich heraus, dass das hochgeladene Formularfeld einen ähnlichen Namen erhält: Blob157fce71535b4f93ba92ac6053d81e3a

Gibt es eine Möglichkeit, diesen Dateinamen clientseitig festzulegen oder zu empfangen, ohne serverseitige Kommunikation durchzuführen?

Antworten:


146

Verwenden Sie für Chrome, Safari und Firefox einfach Folgendes:

form.append("blob", blob, filename);

(siehe MDN-Dokumentation )


Wo hast du das bemerkt ??? Das ist toll! Gibt es einen Link zur Unterstützung dieser Chrome-Versionen?
Dmitrii Sorin

Übrigens, dies ist in der Spezifikation: w3.org/TR/XMLHttpRequest2/#interface-formdata
Dmitrii Sorin

1
Außerdem arbeite ich an dem Firefox-Fehler, um dieses Problem zu beheben. Ich habe ihn bereits behoben, aber ich habe einige " Stilprobleme ". Bugzilla.mozilla.org/show_bug.cgi?id=690659 (ich habe derzeit keine Zeit mehr dafür Repariere diesen Patch, also wenn jemand ihn abholen will, bin ich mehr als zufrieden damit)
Chiguireitor

@Chiguireitor ist es noch nicht behoben?
Will

3
Hier ist die "Kompatibilitätstabelle" von MDN. Beachten Sie, dass ab diesem Beitrag das Anhängen mit Dateiname in allen Browsern außer Chrome und FF eine wackelige Unterstützung bietet: developer.mozilla.org/en-US/docs/Web/API/…
Adam

33

Fügen Sie dies hier hinzu, da es nicht hier zu sein scheint.

Neben der hervorragenden Lösung von können form.append("blob",blob, filename);Sie den Blob auch in eine FileInstanz verwandeln :

var blob = new Blob([JSON.stringify([0,1,2])], {type : 'application/json'});
var fileOfBlob = new File([blob], 'aFileName.json');
form.append("upload", fileOfBlob);

1
Problem ist, dass Sie die Datei / den Blob aus der Zwischenablage erhalten. Was Sie beschreiben, hängt mit dieser Frage zusammen: stackoverflow.com/questions/27251953/…
jontro

9
funktioniert im IE nicht, da der Dateikonstruktor immer noch nicht unterstützt wird.
Mahib

Die Dokumentation vonFile @Mahib MDN zum Konstruktor legt nahe, dass es ab IE10 unterstützt wird.
Robert K. Bell

2
@ RobertK.Bell, ich habe Edge praktisch überprüft und es hat nicht funktioniert :(, dann musste ich wieder zum Blob-Konstruktor wechseln.
Mahib

1
@ Mahib Sie haben Recht - Problem # 9551546 auf Edge Tracker File Konstruktor löstFunction Expected Ausnahme aus
Robert K. Bell

3

Da die Daten in die Zwischenablage eingefügt werden, gibt es keine zuverlässige Methode, um den Ursprung der Datei und ihre Eigenschaften (einschließlich des Namens) zu ermitteln.

Am besten erstellen Sie ein eigenes Dateinamenschema und senden es zusammen mit dem Blob.

form.append("filename",getFileName());
form.append("blob",blob);

function getFileName() {
 // logic to generate file names
}

1
Die Frage fragt nicht nach dem ursprünglichen Dateinamen. Diese Antwort ist völlig falsch.
Niels Abildgaard

2
@NielsAbildgaard: Wirklich? Es wird nach der Zuweisung eines Dateinamens gefragt, und gilt der ursprüngliche Dateiname nicht als gültiger Dateiname?
Mrchief

1
Die Antwort beantwortet nicht die ursprüngliche Frage (außer "Hier ist eine Alternative") und bietet eine Antwort auf etwas, das nicht gestellt wird und offen gesagt nicht zum Thema gehört.
Niels Abildgaard

2

Dieser Name scheint von einer Objekt-URL-GUID abgeleitet zu sein. Gehen Sie wie folgt vor, um die Objekt-URL abzurufen, von der der Name abgeleitet wurde.

var URL = self.URL || self.webkitURL || self;
var object_url = URL.createObjectURL(blob);
URL.revokeObjectURL(object_url);

object_urlwird wie blob:{origin}{GUID}in Google Chrome und moz-filedata:{GUID}in Firefox formatiert . Ein Ursprung ist das Protokoll + Host + Nicht-Standard-Port für das Protokoll. Zum Beispiel blob:http://stackoverflow.com/e7bc644d-d174-4d5e-b85d-beeb89c17743oder blob:http://[::1]:123/15111656-e46c-411d-a697-a09d23ec9a99. Sie möchten wahrscheinlich die GUID extrahieren und alle Striche entfernen.


1

Ich habe es nicht getestet, aber das sollte die URL der Blobs-Daten alarmieren:

var blob = event.clipboardData.items[0].getAsFile(), 
    form = new FormData(),
    request = new XMLHttpRequest();

var reader = new FileReader();
reader.onload = function(event) {
  alert(event.target.result); // <-- data url
};
reader.readAsDataURL(blob);

Dies wird Blob tatsächlich als Daten-URL alarmieren. Was ich erhalten / festlegen möchte, ist der Dateiname, der beim Hochladen eines Formulars an das Formularfeld angehängt wird.
Jontro

Dann kenne ich keinen Weg ohne serverseitige Kommunikation.
JochenJung

0

Es hängt wirklich davon ab, wie der Server auf der anderen Seite konfiguriert ist und mit welchen Modulen er einen Blob-Beitrag behandelt. Sie können versuchen, den gewünschten Namen in den Pfad für Ihren Beitrag einzufügen.

request.open(
    "POST",
    "/upload/myname.bmp",
    true
);

0

Verwenden Sie Google App Engine? Sie können Cookies (mit JavaScript erstellt) verwenden, um eine Beziehung zwischen Dateinamen und dem vom Server empfangenen Namen aufrechtzuerhalten.


0

Wenn Sie Google Chrome verwenden, können Sie das hierfür verwenden / missbrauchen Google Filesystem API. Hier können Sie eine Datei mit einem bestimmten Namen erstellen und den Inhalt eines Blobs darauf schreiben. Anschließend können Sie das Ergebnis an den Benutzer zurückgeben.

Ich habe noch keinen guten Weg für Firefox gefunden. Wahrscheinlich ist ein kleines Stück Flash downloadifyerforderlich, um einen Blob zu benennen.

IE10 hat eine msSaveBlob()Funktion in der BlobBuilder.

Vielleicht ist dies mehr zum Herunterladen eines Blobs, aber es ist verwandt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.