Verwenden von FormData-Objekten
Das FormData
-Objekt ermöglicht es Ihnen, eine Menge von Schlüssel/Wert-Paaren zu erstellen, die mit der Fetch- oder XMLHttpRequest-API gesendet werden können. Es ist hauptsächlich zum Senden von Formulardaten gedacht, kann aber unabhängig von Formularen verwendet werden, um Schlüssel-Daten zu übermitteln. Die übertragenen Daten haben dasselbe Format, das die submit()
-Methode des Formulars verwenden würde, um die Daten zu senden, wenn der Codierungstyp des Formulars auf multipart/form-data
eingestellt wäre.
Erstellen eines FormData
-Objekts von Grund auf
Sie können ein FormData
-Objekt selbst erstellen, indem Sie es instanziieren und dann Felder hinzufügen, indem Sie seine append()
-Methode aufrufen, wie folgt:
const send = document.querySelector("#send");
send.addEventListener("click", async () => {
const formData = new FormData();
formData.append("username", "Groucho");
formData.append("accountNum", 123456);
// A file <input> element
const avatar = document.querySelector("#avatar");
formData.append("avatar", avatar.files[0]);
// JavaScript file-like object
const content = '<q id="a"><span id="b">hey!</span></q>';
const blob = new Blob([content], { type: "text/xml" });
formData.append("webmasterFile", blob);
const response = await fetch("http://example.org/post", {
method: "POST",
body: formData,
});
console.log(await response.json());
});
Hinweis:
Die Felder "avatar"
und "webmasterFile"
enthalten beide eine Datei. Die der Feldzuweisung zugeordnete Zahl "accountNum"
wird unmittelbar durch die FormData.append()
-Methode in einen String umgewandelt (der Wert des Feldes kann ein Blob
, ein File
oder ein String sein. Wenn der Wert weder ein Blob
noch eine File
ist, wird der Wert in einen String umgewandelt).
Dieses Beispiel erstellt eine FormData
-Instanz mit Werten für Felder namens "username"
, "accountNum"
, "avatar"
und "webmasterFile"
und verwendet dann fetch()
, um die Daten des Formulars zu senden. Das Feld "webmasterFile"
ist ein Blob
. Ein Blob
-Objekt stellt ein dateiähnliches Objekt aus unveränderlichen, rohen Daten dar. Blobs repräsentieren Daten, die nicht unbedingt in einem JavaScript-nativen Format vorliegen. Das File
-Interface basiert auf Blob
, erbt die Blob-Funktionalität und erweitert sie, um Dateien auf dem System des Benutzers zu unterstützen. Um ein Blob
zu erstellen, können Sie den Blob()
-Konstruktor aufrufen.
Abrufen eines FormData
-Objekts aus einem HTML-Formular
Um ein FormData
-Objekt zu konstruieren, das die Daten eines bestehenden <form>
enthält, geben Sie dieses Formularelement beim Erstellen des FormData
-Objekts an:
Hinweis:>FormData
verwendet nur Eingabefelder, die das name
-Attribut verwenden.
const formData = new FormData(someFormElement);
Zum Beispiel:
const send = document.querySelector("#send");
send.addEventListener("click", async () => {
// A <form> element
const userInfo = document.querySelector("#user-info");
const formData = new FormData(userInfo);
const response = await fetch("http://example.org/post", {
method: "POST",
body: formData,
});
console.log(await response.json());
});
Sie können dem FormData
-Objekt auch zusätzliche Daten hinzufügen, nachdem Sie es aus einem Formular abgerufen haben und bevor Sie es senden, wie folgt:
const send = document.querySelector("#send");
send.addEventListener("click", async () => {
const userInfo = document.querySelector("#user-info");
const formData = new FormData(userInfo);
formData.append("serialnumber", 12345);
const response = await fetch("http://example.org/post", {
method: "POST",
body: formData,
});
console.log(await response.json());
});
Dies ermöglicht es Ihnen, die Daten des Formulars vor dem Versand anzureichern, um zusätzliche Informationen einzuschließen, die nicht unbedingt vom Benutzer bearbeitbar sind.
Versenden von Dateien mit einem FormData
-Objekt
Sie können auch Dateien mit FormData
senden. Fügen Sie ein <input>
-Element des Typs file
in Ihr <form>
ein:
<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo">
<p>
<label
>Your email address:
<input
type="email"
autocomplete="on"
name="userid"
placeholder="email"
required
size="32"
maxlength="64" />
</label>
</p>
<p>
<label
>Custom file label:
<input type="text" name="file-label" size="12" maxlength="32" />
</label>
</p>
<p>
<label
>File to stash:
<input type="file" name="file" required />
</label>
</p>
<p>
<input type="submit" value="Stash the file!" />
</p>
</form>
Dann können Sie es mit folgendem Code senden:
const form = document.querySelector("#fileinfo");
form.addEventListener("submit", async (event) => {
const formData = new FormData(form);
formData.append("CustomField", "This is some extra data");
const response = await fetch("stash.php", {
method: "POST",
body: formData,
});
event.preventDefault();
});
Hinweis:
Wenn Sie eine Referenz zum Formular übergeben, wird die im Formular angegebene HTTP-Anfragemethode anstelle der in der open()
-Aufruf angegebenen Methode verwendet.
Warnung:
Wenn Sie FormData
verwenden, um POST-Anfragen mit XMLHttpRequest
oder der Fetch API mit dem multipart/form-data
-Content-Type zu senden (z.B. beim Hochladen von Dateien und Blobs zum Server), setzen Sie nicht explizit den Content-Type
-Header in der Anfrage. Andernfalls kann der Browser den Content-Type
-Header mit dem Grenzausdruck, den er verwenden wird, um Formularfelder im Anfragetext zu trennen, nicht setzen.
Sie können auch eine File
oder Blob
direkt zum FormData
-Objekt hinzufügen, wie folgt:
data.append("myfile", myBlob, "filename.txt");
Wenn Sie die append()
-Methode verwenden, ist es möglich, den dritten optionalen Parameter zu verwenden, um einen Dateinamen innerhalb des Content-Disposition
-Headers, der an den Server gesendet wird, zu übergeben. Wenn kein Dateiname angegeben ist (oder der Parameter nicht unterstützt wird), wird der Name "blob" verwendet.
Verwendung eines formdata
-Events
Das formdata
-Ereignis, das neuer als das FormData
-Objekt ist, wird auf einem HTMLFormElement
-Objekt ausgelöst, nachdem die Eintragsliste, die die Formulardaten repräsentiert, erstellt wurde. Dies geschieht beim Absenden des Formulars, kann aber auch durch den Aufruf eines FormData()
-Konstruktors ausgelöst werden.
Dies ermöglicht es, ein FormData
-Objekt schnell in Antwort auf ein formdata
-Ereignis zu erhalten, anstatt es selbst zusammenstellen zu müssen.
Zum Beispiel können wir im JavaScript ein Formular referenzieren:
const formElem = document.querySelector("form");
In unserem submit
-Ereignis-Handler verwenden wir preventDefault
, um die Standardformularübermittlung zu stoppen, und rufen dann einen FormData()
-Konstruktor auf, um das formdata
-Ereignis auszulösen:
formElem.addEventListener("submit", (e) => {
// on form submission, prevent default
e.preventDefault();
// construct a FormData object, which fires the formdata event
new FormData(formElem);
});
Wenn das formdata
-Ereignis ausgelöst wird, können wir auf das FormData
-Objekt über FormDataEvent.formData
zugreifen und damit machen, was wir möchten (unten posten wir es mit XMLHttpRequest
an den Server).
formElem.addEventListener("formdata", (e) => {
console.log("formdata fired");
// Get the form data from the event object
const data = e.formData;
for (const value of data.values()) {
console.log(value);
}
// Submit the data via fetch()
fetch("/formHandler", {
method: "POST",
body: data,
});
});
Stolpersteine
Das FormData
-Objekt enthält keine Daten aus Feldern, die deaktiviert sind, oder aus deaktivierten Fieldsets.