HTML5 FormData zum Serialisieren von Formulareingaben, Upload

Weniger Programmieraufwand mit dem neuen Objekt FormData

Name, Vorname
Aktionen, senden als:

Rohdaten im Request Message-Body

Klicken Sie bitte oben... 

Erläuterungen

Formulareingaben werden als Schlüssel-Werte-Paare übertragen. Sofern das mit Ajax erfolgen soll, müssen diese Eingaben serialisiert werden für einen enctype="application/x-www-form-urlencoded", dies erledigte vor HTML5 entweder eine zusätzliche Library oder es wurde händisch, über die DOM-Element-ID programmiert.

Mit dem neuen JS-Objekt FormData vereinfacht sich diese Angelegenheit enorm. Dem Konstruktor wird ganz einfach das "Formular" übergeben:

    # Button im Formular
    <input type="button" value="Senden als multipart/form-data" onClick="return mpshow.call(this.form);">

    # Für den Ajax-Request
    var formData = new FormData("Das Formular, siehe oben: this.form");

    xhr.send(formData);

Und das wars auch schon. Aber schauen wir mal hinter die Kulissen, wie das beim Server ankommt, das sehen Sie mit einem Klick auf den ersten Button oben im Formular. Das Popup zeigt Ihnen exakt die gesendeten Daten, die serverseitig bei einem POST aus STDIN gelesen werden. Wenn Sie FormData verwenden, funktioniert das verständlicherweise nur bei einem POST mit dem enctype="multipart/form-data".

Der andere Button zeigt Ihnen, wie die Daten, ebenfalls in einem POST mit dem enctype="application/x-www-form-urlencoded" übertragen werden. Auch dieser String wird bei einem POST aus STDIN gelesen serverseitig. Für die Übertragung mit diesem enctype müssen Sie jedoch das Formular entweder händisch serialisieren oder mit Hilfe einer geeigneten Library.

Zum weiteren Verständnis: Der clientseitig codierte enctype ergibt den HTTP-Request-Header Content-Type, womit der serverseitige Prozess erkennen kann, wie die Eingaben zu parsen sind, dafür wird auch die Boundary im Request-Header mitgeliefert. Ein Content-Type-Reponse-Header hingegen gibt dem Client bekannt, welche Inhalte zu erwarten sind, z.B. text/html oder image/gif.

File Upload

Das FormData-Objekt ermöglicht das Upload, ohne dass eine Datei physikalisch über formular-input-type-file eingefügt wird. Der serverseitige Prozess erkennt ein Upload daran, dass es im Komponenten-Header den Parameter filename gibt. Zur Erinnerung: Der Enctype="multipart/form-data" beschreibt eine Multipart-Message, sie besteht aus mehreren Komponenten. Jede Komponente (subpart) hat einen eigenen Header, welcher optional den Content-Type beschreibt und die einzelnen Komponenten sind mit einer boundary voneinander getrennt, Beispiel siehe oben.

Maßgeblich dafür, dass ein solches Upload emuliert wird: Aus den Eingaben ins DOM wird ein Blob erstellt:

    formData.append('file', new Blob([data], { type: 'text/plain; charset=UTF-8'  }));

Und damit die Methode FormData.append() aufgerufen.

Serverseitig

Die schlankere Alternative zu CGI.pm: ParseMultipart.pm

Der Aufbau einer AJAX-Response

Grundsätzlich überträgt HTTP keine Objekte sondern Bytesequenzen, egal ob JSON oder XML. Für obenstehende DEMO wird ein FormData-Objekt im scalaren Kontext gesendet und auch wieder empfangen. Das heißt: Übertragen werden serialisierte Daten, nicht jedoch das Objekt an sich.

Die übertragene Bytesequenz enthält jedoch alle Daten, die eine Wiederherstellung abstrakter Datenstrukturen ermöglichen. Letztendlich jedoch, gibt es zweckmäßigere Lösungen zum Serialisieren komplexer und insbesondere zyklischer Datenstukturen. Für einen asynchronen Request werden verschiedene Response-Types akzeptiert (Default ist text):

xhr.responseType = 'text' || ['arraybuffer', 'blob', 'document']

Der callback-Funktion wird dann callbackfunktion(xhr.response); übergeben, wenn responseType klassifiziert wurde.


Anbieter: nmq​rstx-18­@yahoo.de, die Seite verwendet funktionsbedingt einen Session-Cookie und ist Bestandteil meines nach modernen Aspekten in Perl entwickelten Frameworks.