¿Limitar el formato de archivo al usar <input type="file">?

Resuelto Bojangles asked hace 13 años • 12 respuestas

Me gustaría restringir el tipo de archivo que se puede elegir en el selector de archivos del sistema operativo nativo cuando el usuario hace clic en el botón Examinar en el <input type="file">elemento en HTML. Tengo la sensación de que es imposible, pero me gustaría saber si hay alguna solución. Me gustaría limitarme únicamente a HTML y JavaScript; sin flash por favor.

Bojangles avatar Dec 02 '10 03:12 Bojangles
Aceptado

En rigor, la respuesta es no . Un desarrollador no puede impedir que un usuario cargue archivos de cualquier tipo o extensión mediante la validación de front-end (HTML/JavaScript).

Pero aún así, el atributo de aceptación de <input type = "file">puede ayudar a proporcionar un filtro en el cuadro de diálogo de selección de archivos proporcionado por el navegador/sistema operativo del usuario. Por ejemplo,

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

debería proporcionar una forma de filtrar archivos que no sean .xls o .xlsx. Aunque la página MDNinput para element siempre decía que admite esto, para mi sorpresa, esto no funcionó para mí en Firefox hasta la versión 42. Esto funciona en IE 10+, Edge y Chrome.

Entonces, para admitir Firefox anterior a 42 junto con IE 10+, Edge, Chrome y Opera, supongo que es mejor usar una lista de tipos MIME separados por comas:

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

[ Comportamiento de Edge (EdgeHTML): el menú desplegable de filtro de tipo de archivo muestra los tipos de archivos mencionados aquí, pero no es el valor predeterminado en el menú desplegable. El filtro predeterminado es All files (*).]

También puedes utilizar asteriscos en tipos MIME. Por ejemplo:

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

W3C recomienda a los autores que especifiquen tanto los tipos MIME como sus correspondientes extensiones en el acceptatributo. Entonces, el mejor enfoque es:

<!-- Right approach: Use both file extensions and their 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" /> 
Expandir fragmento

JSFiddle de lo mismo: aquí .

Referencia: Lista de tipos MIME

IMPORTANTE: El uso del acceptatributo solo proporciona una forma de filtrar los archivos de tipos que son de interés. Los navegadores todavía permiten a los usuarios elegir archivos de cualquier tipo. Se deben realizar comprobaciones adicionales (del lado del cliente) (usando JavaScript, una forma sería esta ), y definitivamente los tipos de archivos DEBEN verificarse en el servidor , usando una combinación de tipo MIME usando tanto la extensión del archivo como su firma binaria ( ASP .NET , PHP , Ruby , Java ). Es posible que también desee consultar estas tablas para conocer los tipos de archivos y sus números mágicos , para realizar una verificación más sólida del lado del servidor.

Aquí hay tres buenas lecturas sobre carga de archivos y seguridad.

EDITAR: Tal vez la verificación del tipo de archivo usando su firma binaria también se pueda realizar en el lado del cliente usando JavaScript (en lugar de simplemente mirar la extensión) usando HTML5 File API, pero aún así, el archivo debe verificarse en el servidor, porque un usuario malintencionado Aún podrá cargar archivos realizando una solicitud HTTP personalizada.

Sachin Joseph avatar May 16 '2014 23:05 Sachin Joseph

Existe el atributo de aceptación para la etiqueta de entrada. Sin embargo, no es confiable de ninguna manera. Lo más probable es que los navegadores lo traten como una "sugerencia", lo que significa que el usuario, dependiendo también del administrador de archivos, tendrá una preselección que solo muestra los tipos deseados. Aún pueden elegir "todos los archivos" y cargar cualquier archivo que deseen.

Por ejemplo:

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

Lea más en la especificación HTML5

Tenga en cuenta que sólo debe usarse como "ayuda" para que el usuario encuentre los archivos correctos. Cada usuario puede enviar cualquier solicitud que desee a su servidor. Siempre hay que validar todo en el lado del servidor.

Entonces la respuesta es: no, no puedes restringir , pero puedes establecer una preselección pero no puedes confiar en ella.

Alternativa o adicionalmente puedes hacer algo similar comprobando el nombre del archivo (valor del campo de entrada) con JavaScript, pero esto no tiene sentido porque no proporciona protección y tampoco facilita la selección para el usuario. Potencialmente, sólo engaña al webmaster haciéndole creer que está protegido y abre un agujero de seguridad. Puede ser una molestia para los usuarios que tienen extensiones de archivo alternativas (por ejemplo, jpeg en lugar de jpg), mayúsculas o ninguna extensión de archivo (como es común en los sistemas Linux).

The Surrican avatar Dec 01 '2010 20:12 The Surrican