Mehrere Dateien auf den Server laden
FormData kümmert sich automatisch um die Codierung der Daten mitsamt der Umsetzung von Leerzeichen und Sonderzeichen. Das Fetch-API versendet die Daten asynchron ohne viele Aufhebens im Hintergrund.
<input type="file" id="photos" name="photos[]" multiple> <div class="msg"></div> <div class="filelist"></div> <div class="result"></div>
FileReader für Thumbnail-Vorschau
Ein einfaches HTML-Formular würde zusammen mit der PHP-Anwendung schon ausreichen, um Dateien auf den Server zu laden. Allerdings läuft der Prozess dann kommentarlos ab, der Benutzer würde keine Vorschaubilder sehen und weder über Fehler noch über Erfolg der Aktion unterrichtet. Das FileReader-Objekt liest über input type="file" Dateien vom Rechner des Benutzers in eine FileList. FileReader.readAsDataURL () enthält bei Erfolg eine data:URL als Darstellung der Datei.
const fileSelect = document.getElementById('photos'); document.getElementById('photos').addEventListener('change', function (event) { let files = event.target.files; // FileList for (let i = 0, f; f = files[i]; i++) { if (!f.type.match('image.*')) continue; const reader = new FileReader(); reader.onload = (function(theFile) { return function(e) { const img = document.createElement ("img"); img.src = e.target.result; img.classList.add("thumb"); document.querySelector ('.filelist').append(img) }; })(f); reader.readAsDataURL(f); } const button = document.createElement ("button"); button.id = "upload"; button.innerHTML = "Hochladen"; document.querySelector ("body").append (button); button.addEventListener ("click", upload); });
Wenn das input-Element mehr als eine Datei erlaubt, ist input.files ein Array-ähnliches Objekt mit den Dateien. Kann nur eine einzelne Datei geladen werden, liegt sie in input.files[0]. Dass die Thumbnails für die geladenen Bilder (zumindest bei kleinen Bildern) hier so schnell erscheinen, liegt natürlich daran, dass sie noch nicht auf den Server geladen sind, sondern noch im Speicher des Browsers liegen. Wenn große Bilddateien mit mehreren Megabyte ausgewählt werden, braucht auch der Browser u.U. sichtbar Zeit, um die Thumbnails zu erstellen.
Am Ende erzeugt das Skript den Button für den Upload.
FormData.append()
FormData erspart das Zusammenstellen eines Post-Requests / JSON-Objekts aus den Eingabefeldern des Formulars, kann Files, Blobs und Strings mit append übernehmen sowie benutzerdefinierte Schlüssel-Wert-Paare (z.B. den Benutzernamen) hinzufügen und versenden.
// Files formData.append(name, file, filename); // Blobs formData.append(name, blob, filename); // Strings formData.append(name, value);
Der tatsächliche Upload auf den Server beginnt, wenn der User die Daten mit dem »Laden«-Button abschickt. Das progress-Element wird sichtbar.
function upload () {
document.querySelector(".result").innerHTML = "";
document.querySelector('progress').style = "display: block";
const files = fileSelect.files;
const formData = new FormData();
for (const item of files) {
if (!item.type.match('image.*')) {
continue;
}
formData.append('photos[]', item, item.name);
};
formData.append('username', 'Martina Schmitz');
fetch ("upload.php", {
method: "POST",
body: formData
})
.then (response => response.json ())
.then (data => {
console.log ("Antwort vom Server", data);
document.querySelector ("#upload").remove ();
document.querySelector ('.filelist').innerHTML = '';
document.querySelector (".result").innerHTML = data.data + " Status: "+ data.status;
});
};
PHP Upload mehrerer Dateien
Nur rudimentär: Nur PNG ist zugelassen, Dateigröße beschränkt. PHP lädt Dateien zunächst in ein temporäres Verzeichnis, erst wenn das so funktioniert, werden die Dateien in das endgültige Verzeichnis auf dem Server bewegt und aus dem temporären Verzeichnis gelöscht.
<?php
// JSON – Ausgabe
function outputJSON($msg, $status = 'error'){
header('Content-Type: application/json');
die(json_encode(array(
'data' => $msg,
'status' => $status
)));
}
/** Über alle Dateien laufen
und den Pfad für den Dateispeicher setzen
**/
$target_dir = " … Pfad zum Verzeichnis auf dem Server … ";
if ( isset($_FILES['photos']['name']) ) {
$total_files = count($_FILES['photos']['name']);
for($key = 0; $key < $total_files; $key++) {
// Check if file is selected
if (isset($_FILES['photos']['name'][$key])
&& $_FILES['photos']['size'][$key] > 0) {
// Check filetype
if($_FILES['photos']['type'][$key] != 'image/png'){
outputJSON('Dateityp muss PNG sein.');
}
if(!getimagesize($_FILES['photos']['tmp_name'][$key])){
outputJSON('Datei ist kein Bild.');
}
// Check filesize
if($_FILES['photos']['size'][$key] > 500000){
outputJSON('Dateigröße überschreitet Max 500KB.');
}
// Check ob der Dateiname bereits existiert
if(file_exists ($target_dir . $_FILES['photos']['name'][$key])){
outputJSON('Eine Datei mit diesem Namen existiert bereits.');
}
$original_filename = $_FILES['photos']['name'][$key];
$target = $target_dir . basename($original_filename);
$tmp = $_FILES['photos']['tmp_name'][$key];
move_uploaded_file($tmp, $target);
}
}
outputJSON ( $total_files . ' Dateien in das Verzeichnis UPLOADS geladen ', 'OK');
}
Fotos von mobilen Geräten hochladen
Auch die mobilen Geräte wie Tablet oder Smartphone bieten den Upload von Dateien aus dem Album des Geräts an.
Fotos aus der Kamera werden geladen mit
<input type="file" accept="image/*" capture="camera">