Wie schon beschrieben, kann man mit HTML5 die Datei-Auswahl zum Dateiupload so einrichten, dass mehrere Dateien ausgewählt werden können. Am Ende des Artikels hatte ich darauf hingewiesen, dass es empfehlenswert ist die Dateigrößen vor dem Upload zu überprüfen um unnötigen Traffic und/oder Serververfehler zu vermeiden.
Hier nun die Javascript-Lösung des Problems. Es gibt mehrere Browsereigenheiten zu beachten. Neben den Dateigrößen muss auch die Gesamtgröße aller Dateien geprüft werden.
Auch hier muss wieder bedacht werden, dass natürlich ein Browser das alles gar nicht kann.
[ad#More_Tag_Ad]
Warum nicht mit PHP?
Die Dateigrößen erst serverseitig mit PHP zu prüfen ist suboptimal. Zum einen kann es bei zu großen Dateien schon vorher zu Fehlern kommen, die einen Aufruf des PHP Scripts verhindern. Viel wichtiger ist aber, dass dazu ja zuerst die Dateien hochgeladen werden müssen. der User wartet also u.U. minutenlang und seine Dateien werden übertragen, damit der Server am Ende meldet dass es des Guten zuviel war. Viel benutzerfreundlicher ist es aber, dem User schon vor dem Upload mitzuteilen ob das überhaupt klappt und im besten Fall den Upload sogar zu verhindern. Das geht nur mit Javascript .. oder auch nicht.
Die Browsereigenheiten
Um die Dateinamen und Dateigrößen zu erfahren, müssen wir die entsprechenden Einträge im Input-Objekt auslesen. Dabei begegnen uns 3 Browsereigenheiten. Als erstes möchte ich die gravierendste nennen: Der Internet Explorer bietet uns da nichts an. Wir müssen das Formular in jedem Fall absenden und den User warten und bangen lassen. Zweitens und Drittens: Beim Opera heißen die Einträge im Input-Objekt anders als in Firefox, Chrome und Safari.
Scriptablauf
Das Script prüft also zu erst, ob es sich um einen IE handelt und sendet das Forular in diesem Fall ungeprüft ab. Danach wird festgestellt ob es ein Opera ist, und im späteren Verlauf in Abhängigkeit dazu unterschiedliche Variablen im input-Objekt abgefragt. Findet das Script eine zu große Datei oder ist die Gesamtgröße zu hoch, gibt es ein false zurück ansonsten ein true. Dadurch dass wir diesen Rüchgabewert an den onclick-Event des Submitbuttons liefern, entscheiden wir so, ob das Formular abgesendet wird oder nicht.
Zur Kontrolle zeigt das Script eine Statusmeldung zu jeder Datei. Verwendet man das Script mit dem Opera, kann man hier auch schön sehen, wie tatsächlich Dateien hinzugefügt werden können, die Leiste aber nie ersetzt werden kann. Ziemlich böse ist, dass man so auch eine Datei mehrmals auswählen kann. Der Opera prüft nicht, ob die Datei schon in der Liste vorhanden ist.
Fazit
Da der IE weder das HTML5-Multi-Fileupload unterstützt, noch in Javascript alle nötigen Informationen zu hochladbaren Dateien anbietet, muss man diesen Browser einfach vernachlässigen und dem User leider das anbieten was der Browser von Haus aus macht. Unnötige Wartezeit und Traffic verursachen. Bei den anderen wichtigen Browsern kommen wir zu einer besseren Lösung und können so unnötige Serverfehler, unnötigen Traffic und unnötige Wartezeiten für unsere Seitenbesucher vermeiden. Kommt der User nicht mit einem Opera, hat er sogar die Möglichkeit seine Dateiauswahl zu korrigieren.
Ergänzende Links
Der Quelltext
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<title>TEST</title>
-
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-
<meta http-equiv="Content-Language" content="de"/>
-
<meta http-equiv="expires" content="0"/>
-
<script type="text/javascript">
-
function checksizes(datei){
-
// Wenns der IE ist, können wir nix machen und müssen das Formular absenden
-
// So wird durch den IE unnötiger Traffic erzeugt und der User rennt ins offene Messer
-
if(navigator.appName.indexOf("Internet Explorer") != -1){
-
return true;
-
}
-
-
// Bist du ein Opera?
-
var opera = (navigator.userAgent.indexOf(‘Opera’) != -1);
-
-
// erst einmal ist alles schön
-
var result = true;
-
-
// Die Maximalgrößen
-
var mb2 = 2 * 1024 * 1024;
-
var mb5 = 5 * 1024 * 1024;
-
var mb8 = 8 * 1024 * 1024; // post_max_size
-
var maxfilesize = mb2;
-
var maxpostsize = mb8;
-
-
var postsize = 0;
-
var filesize = 0;
-
var filename = ”;
-
-
// Die Statusausgabe
-
var ausgabe = document.getElementById(‘ausgabe’);
-
// Zuerst die Ausgabe löschen
-
ausgabe.innerHTML = ”;
-
-
// Wir gehen alle files durch. Nur mit HTML5 (außer IE) sind multiple Fileuploads möglich.
-
// Bei HTML4, XHTML usw. stehen die Daten zu dem einzigen File in files[0]
-
for(i=0; i < datei.files.length; i++){
-
filesize = (opera) ? datei.files[i].size : datei.files[i].fileSize;
-
postsize += filesize;
-
if(filesize <= maxfilesize){
-
var uploadstatus = ‘<span style="color:#00a000">OK</span>’;
-
}else{
-
var uploadstatus = ‘<span style="color:#f00000">Zu Groß!</span>’;
-
// delete datei.files[i]; // Das funktioniert leider nicht, weil wir mit Javascript keinen Schreibzugriff auf die files[] im datei Objekt haben
-
// Deshalb müssen wir schon bei nur einem zu großen File abbrechen!
-
result = false;
-
-
}
-
-
filename = (opera) ? datei.files[i].name : datei.files[i].fileName;
-
// Den Dateistatus in die Ausgabe schreiben
-
ausgabe.innerHTML += ‘<p>Datei: ‘ + filename + ‘ - Status: ‘ + uploadstatus + ‘</p>n<hr>n‘
-
}
-
-
// noch prüfen, ob die post_max_size nicht überschritten wurde
-
if(postsize > maxpostsize){
-
result = false;
-
ausgabe.innerHTML += ‘<p style="color:#f00000;">Die Gesamtgröße aller Dateien beträgt: ‘ + postsize + ‘byte<br>Maximale Gesamtgröße ist: ‘ + maxpostsize + ‘byte</p>n<hr>n‘
-
}
-
// true = der onclick Event wird weitergegeben und vom SUbmitbutton ausgeführt
-
// false = der onclick Event wird abgebrochen und vom Submit Button nicht weiter verarbeitet, das Formular also nicht abgesendet.
-
-
return result;
-
}
-
</script>
-
</head>
-
<body>
-
<form action="./checkfilesize.html" method="post" enctype="multipart/form-data">
-
-
<!- Das Attribut "multiple" gibt es nur in HTML5 und wird *NICHT* vom IE unterstützt. Trotzdem hier zur Demonstration angewendet ->
-
<input type="file" id="myfile" name="Datei" onchange="checksizes(document.getElementById(‘myfile’));" multiple>
-
-
<!- Wir fangen den onclick Event ab und entscheiden dann ob wir ihn an den Submit Button weitergeben oder nicht. ->
-
<input type="submit" name="Senden" value="Senden" onclick="return checksizes(document.getElementById(‘myfile’));">
-
</form>
-
<div id="ausgabe"></div>
-
</body>
-
</html>
Ein tolles Script. Daß es auf dem IE nicht funktioniert, ist ja kein Wunder, aber leider funktioniert es auf dem Firefox (inzwischen?) auch nicht. Firefox in der aktuellen Version meldet sowohl auf Windows als auch auf Mac nur: “Datei: undefined - Status: Zu Groß!”, egal was für eine Datei und wie groß sie ist. Wäre toll, wenn du das zum Laufen bringen könntest, da der FF ja doch sehr beliebt ist.