Dateiformat bei Verwendung von <input type = “file”> einschränken?

667

Ich möchte den Dateityp einschränken, der aus der Dateiauswahl des nativen Betriebssystems ausgewählt werden kann, wenn der Benutzer <input type="file">im HTML-Element auf die Schaltfläche Durchsuchen klickt . Ich habe das Gefühl , es ist unmöglich, aber ich würde gerne wissen , ob es ist eine Lösung. Ich möchte mich ausschließlich an HTML und JavaScript halten. bitte kein Flash.

Bojangles
quelle
1
Mit PHP ist das leicht möglich, aber ich weiß nicht, ob Sie das verwenden können, also werde ich den Code nicht veröffentlichen.
Latox
2
Ich kann, aber ich habe eine Lösung, die mit JavaScript arbeitet - sie beseitigt den Ärger, eine Datei hochzuladen und dann die "Falsche Datei!" Error.
Bojangles
Siehe auch neuere Frage: stackoverflow.com/questions/181214/…
Christophe Roussy
Zu beachten ist, dass durch Akzeptieren die sichtbaren Dateien auf die akzeptierten Dateien beschränkt werden, während der Benutzer sie durchsucht (zumindest in einigen Browsern ...). Dies ist also eher eine UI-Ergonomiefunktion als eine Validierungsfunktion.
Christophe Roussy

Antworten:

1119

Genau genommen lautet die Antwort nein . Ein Entwickler kann einen Benutzer nicht daran hindern, Dateien jeglicher Art oder Erweiterung hochzuladen.

Das Attribut accept von <input type = "file">kann dennoch dazu beitragen, einen Filter im Dialogfeld zur Dateiauswahl des Betriebssystems bereitzustellen. Zum Beispiel,

<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox 42+) -->
<input type="file" accept=".xls,.xlsx" />

sollte eine Möglichkeit bieten, andere Dateien als .xls oder .xlsx herauszufiltern. Obwohl auf der MDN- Seite für inputelement immer angegeben wurde, dass dies unterstützt wird, funktionierte dies zu meiner Überraschung in Firefox bis Version 42 nicht. Dies funktioniert in IE 10+, Edge und Chrome.

Um Firefox älter als 42 zusammen mit IE 10+, Edge, Chrome und Opera zu unterstützen, ist es wahrscheinlich besser, eine durch Kommas getrennte Liste von MIME-Typen zu verwenden:

<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox) -->
<input type="file"
 accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" /> 

[ Edge (EdgeHTML) -Verhalten: Das Dropdown-Menü für Dateitypfilter zeigt die hier genannten Dateitypen an, ist jedoch nicht die Standardeinstellung in der Dropdown-Liste. Der Standardfilter ist All files (*).]

Sie können auch Sternchen in MIME-Typen verwenden. Zum Beispiel:

<input type="file" accept="image/*" /> <!-- all image types --> 
<input type="file" accept="audio/*" /> <!-- all audio types --> 
<input type="file" accept="video/*" /> <!-- all video types --> 

W3C empfiehlt Autoren, sowohl MIME-Typen als auch entsprechende Erweiterungen im acceptAttribut anzugeben . Der beste Ansatz ist also:

<!-- Right approach: Use both file extensions and corresponding MIME-types. -->
<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox) -->
<input type="file"
 accept=".xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" /> 

JSFiddle desselben: hier .

Referenz: Liste der MIME-Typen

WICHTIG: Die Verwendung des acceptAttributs bietet nur eine Möglichkeit zum Filtern in Dateien von Typen, die von Interesse sind. In Browsern können Benutzer weiterhin Dateien eines beliebigen Typs auswählen. Zusätzliche (Client-Seite) Kontrollen durchgeführt werden soll (mit Hilfe von JavaScript, wäre ein Weg sein , diese ), und auf jeden Fall Dateitypen muss auf dem Server überprüft werden , die eine Kombination von MIME-Typ unter Verwendung von sowohl mit der Dateierweiterung und seine binäre Signatur ( ASP .NET , PHP , Ruby , Java ). In diesen Tabellen finden Sie möglicherweise auch Dateitypen und deren magische Zahlen, um eine robustere serverseitige Überprüfung durchzuführen.

Hier sind drei gute Informationen zu Datei-Uploads und Sicherheit.

BEARBEITEN: Möglicherweise kann die Überprüfung des Dateityps mithilfe seiner binären Signatur auch auf der Clientseite mithilfe von JavaScript (anstatt nur anhand der Erweiterung) mithilfe der HTML5-Datei-API durchgeführt werden. Die Datei muss jedoch auf dem Server überprüft werden, da es sich um einen böswilligen Benutzer handelt Sie können weiterhin Dateien hochladen, indem Sie eine benutzerdefinierte HTTP-Anfrage stellen.

Sachin Joseph
quelle
2
@ Sandesire Ich glaube nicht, dass Sie die Dateigröße in HTML einschränken können. Es ist möglich, JavaScript zu verwenden, wie Sie vorgeschlagen haben.
Sachin Joseph
1
Aus meiner persönlichen Erfahrung scheint dies eine gute Antwort zu sein. Der MIME-Typ allein funktioniert nicht in allen Browsern.
Christophe Roussy
1
Funktioniert übrigens acceptimmer noch nicht in Edge: stackoverflow.com/questions/31875617/… . Weitere Details hier: wpdev.uservoice.com/forums/257854-microsoft-edge-developer/…
SharpC
1
Ich wünschte, wir hätten zum Beispiel die Möglichkeit, auch Dateien auszuschließen exclude="exe". ¯_ (ツ) _ / ¯
Sagiv bg
1
Um das Edge-Verhalten weiter zu verdeutlichen (gemäß meinen Tests), werden je nach Angabe verschiedene Filter hinzugefügt. A) Es wird nicht gebündelt, sodass jede Erweiterung als separate Option aufgeführt wird. B) Es werden immer einige Filter hinzugefügt Erstellen Sie Erweiterungen wie .html und c). Wie bereits erwähnt, wird immer (*) vorausgewählt. Das macht es zu einem großen Durcheinander und in den meisten Fällen nutzlos. Ich habe über den Uservoice-Link abgestimmt. Hoffen wir, dass sie früher oder später zuhören.
Arie
198

Es gibt das Attribut accept für das Eingabe-Tag. Es ist jedoch in keiner Weise zuverlässig. Browser behandeln es höchstwahrscheinlich als "Vorschlag", was bedeutet, dass der Benutzer abhängig vom Dateimanager eine Vorauswahl hat, die nur die gewünschten Typen anzeigt. Sie können weiterhin "alle Dateien" auswählen und jede gewünschte Datei hochladen.

Zum Beispiel:

<form>
    <input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />
</form>

Lesen Sie mehr in der HTML5-Spezifikation

Beachten Sie, dass es nur als "Hilfe" für den Benutzer verwendet werden soll, um die richtigen Dateien zu finden. Jeder Benutzer kann jede gewünschte Anfrage an Ihren Server senden. Sie müssen immer alles serverseitig validieren.

Die Antwort lautet also: Nein, Sie können nicht einschränken , aber Sie können eine Vorauswahl festlegen, aber Sie können sich nicht darauf verlassen.

Alternativ oder zusätzlich können Sie etwas Ähnliches tun, indem Sie den Dateinamen (Wert des Eingabefelds) mit JavaScript überprüfen. Dies ist jedoch Unsinn, da es keinen Schutz bietet und auch die Auswahl für den Benutzer nicht erleichtert. Es täuscht einen Webmaster möglicherweise nur vor, er sei geschützt, und öffnet eine Sicherheitslücke. Für Benutzer mit alternativen Dateierweiterungen (z. B. JPEG anstelle von JPG), Großbuchstaben oder gar keinen Dateierweiterungen (wie es auf Linux-Systemen üblich ist) kann dies ein Ärgernis sein.

Der Surrican
quelle
3
Weitere Informationen finden Sie unter stackoverflow.com/questions/181214/…
Martin Meeser
1
Obwohl es wahr ist, dass es unmöglich ist, den Benutzer daran zu hindern, irgendwann einen Dateityp auszuwählen, können Sie heutzutage die HTML5-Datei-API nutzen und mit der ausgewählten Datei zum Hochladen arbeiten, bevor sie tatsächlich auf den Server hochgeladen wird, einschließlich der Erkennung seine Art, Größe und mehr. Versuche es. Es ist sehr einfach zu bedienen, aber sehr leistungsfähig und nützlich.
TheCuBeMan
96

Sie können das changeEreignis verwenden, um zu überwachen, was der Benutzer auswählt, und ihn an diesem Punkt zu benachrichtigen, dass die Datei nicht akzeptabel ist. Es schränkt die tatsächliche Liste der angezeigten Dateien nicht ein, ist jedoch neben dem schlecht unterstützten acceptAttribut die nächstgelegene, die Sie clientseitig ausführen können.

var file = document.getElementById('someId');

file.onchange = function(e) {
  var ext = this.value.match(/\.([^\.]+)$/)[1];
  switch (ext) {
    case 'jpg':
    case 'bmp':
    case 'png':
    case 'tif':
      alert('Allowed');
      break;
    default:
      alert('Not allowed');
      this.value = '';
  }
};
<input type="file" id="someId" />

JSFiddle

Gabriele Petrioli
quelle
11
@ Joe, es ist ein Beispiel ... es kann sich auf alle Erweiterungen erstrecken, die Sie zulassen möchten.
Gabriele Petrioli
ja du kannst. aber du hast es nicht getan! und maby jemand hat es schon kopiert! und was ist mit Dateien mit korrektem MIME-Typ, aber ohne Erweiterung?
The Surrican
49
@ Joe .. na ja .. ich versuche Richtung und eine solide Logik bereitzustellen. Nicht für jeden Fall vollständig implementierte Lösungen. Ich vertraue darauf, dass die Zuschauer beim Kopieren / Einfügen von Code aus dem Internet den gesunden Menschenverstand verwenden;)
Gabriele Petrioli
7
Wie wäre es mit "Some.File.jpg"? Möglicherweise muss diese Regex-Zeile lauten: var ext = this.value.match (/ \. ([^.] +) $ /) [1];
Jon Kloske
Das Problem bei diesem Ansatz ist, dass etwas technisch gesehen immer noch ein JPEG sein kann, auch wenn es nicht mit dieser Erweiterung endet. Erweiterungen! == MIME-Typen
Matt Fletcher
46

Ja, du hast recht. Mit HTML ist das unmöglich. Der Benutzer kann jede gewünschte Datei auswählen.

Sie können einen Teil des JavaScript- Codes schreiben , um zu vermeiden, dass eine Datei basierend auf ihrer Erweiterung gesendet wird. Beachten Sie jedoch, dass dies einen böswilligen Benutzer keinesfalls daran hindert, Dateien einzureichen, die er wirklich möchte.

Etwas wie:

function beforeSubmit()
{
    var fname = document.getElementById("ifile").value;
    // check if fname has the desired extension
    if (fname hasDesiredExtension) {
        return true;
    } else {
        return false;
    }
}

HTML Quelltext:

<form method="post" onsubmit="return beforeSubmit();">
    <input type="file" id="ifile" name="ifile"/>
</form>
Pablo Santa Cruz
quelle
3
Dafür gibt es ein vollständig gültiges HTML-Attribut, sodass dies möglich ist. Es wird von Browsern einfach nicht respektiert, aber das ist ein Standardisierungsproblem. Ebenso wie alles, was clientseitig in ungeschütztem Markup behandelt wird, kann nichts eingeschränkt werden. Java-Skript ist keine Lösung.
The Surrican
2
Sehr guter Punkt. Ich werde für alle Fälle einen zweiten PHP-Checker hinzufügen. Kann nicht vorsichtig genug sein!
Bojangles
2
Nun, es schadet nicht, wenn ich auch ein PHP-Validierungsskript verwende, also werde ich beide verwenden.
Bojangles
17
@ Joe: Hör auf zu sagen, dass meine Antwort scheiße ist! :-) Auf jeden Fall ist es keine perfekte Lösung. Wie ich am Anfang sagte: "Es ist unmöglich" zu tun, was OP will. Sie können dem Benutzer jedoch ein gewisses Maß an Hilfe bieten, wenn Sie ihn nur Dateien mit bestimmten Erweiterungen auswählen lassen. Die Überprüfung des REAL- Dateityps muss serverseitig erfolgen .
Pablo Santa Cruz
11
@ JoeHopfgartner: Alter, du bist hier zu hart für Pablo. Die clientseitige Validierung wird an unzähligen Stellen durchgeführt und ist zwar nicht kinderleicht (es sollte immer [b] immer eine serverseitige Validierung enthalten sein), kann dem Benutzer jedoch einige Zeit sparen (kein Postback für eine dumme Erweiterungsprüfung usw.). Das von Pablo bereitgestellte Skript ist zwar nicht perfekt, soll jedoch nur ein Beispiel für die Behebung dieses Problems sein. Vielleicht sollten Sie den Technikern von Microsoft eine E-Mail senden und sie bitten, die clientseitige Validierung seitdem von ihren ASP.NET-Validatoren zu entfernen Es ist alles einfacher Müll für dich ...
Nathan
18

Technisch gesehen können Sie das acceptAttribut (Alternative in HTML5 ) für das inputElement angeben , es wird jedoch nicht ordnungsgemäß unterstützt.

zzzzBov
quelle
W3Schools-Browserunterstützung schlägt fehl! Es ist wirklich eine Schande. Dies ist auch ein Sicherheitsrisiko: Benutzer können den clientseitigen Code hacken und alles hochladen, was sie möchten.
Bojangles
5
Es ist zwar am besten, dies nicht aus Sicherheitsgründen zu verwenden, aber es hilft definitiv der Benutzerfreundlichkeit in Browsern, die dies unterstützen. Benutzern werden nur die Dateien angezeigt, die die Site zulässt (nicht alle anderen Junk-Dateien, die sich möglicherweise im selben Ordner befinden), und sie müssen nicht den gesamten Upload-Vorgang durchlaufen, um einen Fehler zu erhalten. Sie werden dies sofort wissen. Codierer sollten dies verwenden.
Simon East
10

Verwenden inputTag mit acceptAttribute

<input type="file" name="my-image" id="image" accept="image/gif, image/jpeg, image/png" />

Klicken Sie hier, um die neueste Browserkompatibilitätstabelle anzuzeigen

Live-Demo hier

Um nur Bilddateien auszuwählen, können Sie diese verwenden accept="image/*"

<input type="file" name="my-image" id="image" accept="image/*" />

Live-Demo hier

Es werden nur GIF, JPG und PNG angezeigt, Screenshot von Chrome Version 44 Es werden nur GIF, JPG und PNG angezeigt, Screenshot von Chrome Version 44

kiranvj
quelle
Vielen Dank! Wenn ich in Chrome unter Win10 accept="image/*""Bilddateien" anstelle von "Benutzerdefinierte Dateien" in der Dateiauswahl verwende, ist dies für den Endbenutzer hilfreich .
Teddy
Aber Benutzer kann es ändern und die andere Erweiterungsdatei hochladen
Prashant Prajapati
@PrashantPrajapati Ja, so werden Browser hergestellt, es sollte eine entsprechende Validierung im Server geben. Die Browser-Funktionalität dient nur der besseren Benutzererfahrung.
Kiranvj
9

Ich weiß, das ist etwas spät.

function Validatebodypanelbumper(theForm)
{
   var regexp;
   var extension =     theForm.FileUpload.value.substr(theForm.FileUpload1.value.lastIndexOf('.'));
   if ((extension.toLowerCase() != ".gif") &&
       (extension.toLowerCase() != ".jpg") &&
       (extension != ""))
   {
      alert("The \"FileUpload\" field contains an unapproved filename.");
      theForm.FileUpload1.focus();
      return false;
   }
   return true;
}
bpross
quelle
5

Sie könnten dies tatsächlich mit Javascript tun, aber denken Sie daran, dass js clientseitig ist. Sie würden also Benutzer "warnen", welche Art von Dateien sie hochladen können, wenn Sie bestimmte Dateitypen vermeiden (einschränken oder einschränken möchten, wie Sie sagten), die Sie MÜSSEN Mach es serverseitig.

Schauen Sie sich dieses grundlegende Tutorial an, wenn Sie mit der serverseitigen Validierung beginnen möchten. Das gesamte Tutorial finden Sie auf dieser Seite .

Viel Glück!

Trufa
quelle
4

Wie in den vorherigen Antworten erwähnt, können wir den Benutzer nicht darauf beschränken, Dateien nur für bestimmte Dateiformate auszuwählen. Es ist jedoch sehr praktisch, das Attribut accept tag on file in HTML zu verwenden.

Die Validierung muss auf der Serverseite erfolgen. Wir können es auch auf Client-Seite in js tun, aber es ist keine narrensichere Lösung. Wir müssen auf der Serverseite validieren.

Für diese Anforderungen bevorzuge ich das Entwicklungsframework für struts2 Java-Webanwendungen. Mit der integrierten Funktion zum Hochladen von Dateien ist das Hochladen von Dateien in struts2-basierte Web-Apps ein Kinderspiel. Erwähnen Sie einfach die Dateiformate, die wir in unserer Anwendung akzeptieren möchten, und der Rest wird vom Kern des Frameworks selbst erledigt. Sie können es auf der offiziellen Website von Struts nachlesen.

svg
quelle
3

Ich kann Folgendes vorschlagen:

  • Wenn Sie den Benutzer standardmäßig dazu bringen müssen, eine der Bilddateien auszuwählen, verwenden Sie accept = "image / *".

    <input type="file" accept="image/*" />

  • Wenn Sie sich auf bestimmte Bildtypen beschränken möchten, verwenden Sie accept = "image / bmp, image / jpeg, image / png".

    <input type="file" accept="image/bmp, image/jpeg, image/png" />

  • Wenn Sie sich auf bestimmte Typen beschränken möchten, verwenden Sie accept = ". bmp, .doc, .pdf".

    <input type="file" accept=".bmp, .doc, .pdf" />

  • Sie können den Benutzer nicht darauf beschränken, den Dateifilter auf alle Dateien zu ändern. Überprüfen Sie daher immer den Dateityp in Skript und Server

Imran Javed
quelle
1
Dies war, wonach ich gesucht habe: accept = ". Bmp" Funktioniert gut auf Chrom.
MichaelRom