2010-08-19 20 views
39
<input type='file' name='userFile'> 

ahora, cuando voy a hacer clic en el botón Examinar, el diálogo de búsqueda mostrará todos los archivos ... ¿Y si quiero filtrar los tipos de archivos que permite decirHTML <input type = 'archivo'> aplicar un filtro

  • sólo imágenes o .png & .jpg & .gifs
  • único archivo de oficina como .doc & .docx & .pps

cómo hacerlo ...

Respuesta

35

Hay un atributo "aceptar" en los controles de entrada de archivos, donde puede especificar los tipos de archivos que desea. Por lo que estoy viendo, a muchos navegadores les gusta ignorarlo: los tipos de archivos que se pueden especificar son MIME, por lo que un navegador estrictamente correcto debería examinar todos los archivos independientemente de la extensión y ver si se trata de una imagen (y si es así, de qué tipo es).

Actualización: Parece al menos alguna versión de todos los principales navegadores en Windows proporciona ahora al menos algún apoyo para el atributo accept. (Incluso IE lo admite, a partir de la versión 10.) Sin embargo, todavía es un poco temprano para confiar en él, ya que IE 8 y 9 aún no lo admiten. Y el apoyo en general es un poco irregular.

  • Chrome parece tener soporte completo. Utiliza su propia lista incorporada de tipos, así como la del sistema ... así que si cualquiera define el tipo, Chrome sabe qué archivos mostrar.
  • IE 10 es compatible con extensiones de archivos muy bien, y los tipos MIME decentemente. Sin embargo, parece usar solo el mapeo del sistema de tipo MIME a extensiones ... lo que básicamente significa que si algo en la computadora del usuario no registró esas extensiones con los tipos MIME correctos, IE no mostrará los archivos de esos tipos MIME.
  • Opera solo parece soportar tipos MIME, hasta el punto en que las extensiones realmente deshabilitan el filtro, y la IU del selector de archivos apesta. Debe seleccionar un tipo para ver los archivos de ese tipo.
  • Firefox parece admitir solo un conjunto limitado de tipos e ignorar otros tipos además de extensiones.
  • No tengo Safari, y no planeo descargarlo. Si alguien puede documentar el soporte de Safari ... Soporte parcial en safari. http://caniuse.com/#search=accept

Debería considerar agregar el atributo, por lo que los navegadores que lo admitan pueden ayudar al usuario a encontrar los archivos correctos más fácilmente. Pero aún sugeriría que verifique el nombre del archivo después de que se haya seleccionado el archivo y muestre un mensaje de error si se carga un archivo con la extensión incorrecta.

Y, por supuesto, definitivamente haga que el servidor compruebe dos veces si el archivo es del tipo correcto. Las extensiones de archivo son solo una convención de nomenclatura y pueden subvertirse fácilmente.E incluso si pudiésemos confiar en el navegador (que no podemos), e incluso si intentara filtrar cosas como usted pidió (lo que podría no ser así), la posibilidad de que realmente verifique que ese archivo .doc es realmente un documento de Word está al lado de nil.

+1

"El atributo de aceptación no es adecuadamente compatible con ninguno de los principales navegadores". (citado de http://www.w3schools.com/TAGS/att_input_accept.asp) – Nick

+0

Nick tiene razón ... intenté con eso – Moon

+5

La página citada ahora dice "El atributo de aceptación es compatible con todos los principales navegadores, excepto Internet Explorer y Safari. " – Mopper

0

que puedes usar one of the plugins que utilizan flash embebido, ya que no puede hacerlo con javascript llanura

+0

gracias pero no, gracias ... prefiero comprobar el tipo de archivo después de haberlo seleccionado ... me va a ahorrar un lote de trabajo – Moon

+3

+1 porque esta es la única solución viable (aunque sería mejor publicar algunos enlaces reales en lugar de una búsqueda en Google que puede cambiar). @Moon necesitará verificar el tipo de archivo después (es decir, después de cargarlo) de todos modos ... Lo único que puede hacer localmente después de seleccionar es verificar la extensión del archivo, que no es un indicador 100% confiable del tipo de archivo real. –

+1

@Pekka As: a partir del HTML 5, un número de navegadores puede [leer los bytes de un archivo seleccionado] (https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications). Todavía no funciona en IE <8, pero dado que la seguridad exige que vuelva a verificar de todos modos, cualquier validación del lado del cliente es realmente solo una forma de evitar que el usuario pierda su tiempo. Y si todavía usan IE8, tan lento como es, aparentemente no les importa perder el tiempo ... :) – cHao

6

No puede controlar qué archivos se pueden seleccionar, pero puede leer el nombre del archivo con javascript después de elegir el archivo. A continuación, podría mostrar una advertencia y/o desactivar el botón de enviar si el archivo es del tipo incorrecto. Sin embargo, recuerde que no puede confiar en la extensión para decirle si el archivo es realmente del tipo correcto o no. Solo se debe tratar como una forma de ayudar a los usuarios que de lo contrario perderían tiempo cargando un archivo enorme antes de descubrir que no es compatible con ese tipo de archivo.

Aquí hay un código de ejemplo para hacer eso. Utiliza jQuery, pero también podrías hacer lo mismo en javascript.

$(function() { 
    $('#inputId').change(function() { 
     var filename = $(this).val(); 
     if (! /\.txt$/.test(filename)) { 
      alert('Please select a text file'); 
     } 
    }); 
}); 
+0

¿cómo se usaría esto para múltiples tipos de archivos? – Jdoonan

36

Creo que está buscando el parámetro de aceptación. Prueba esto funciona

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

He hecho una manera fácil de f o validación del lado del cliente para la mayoría de los casos en el filtrado de archivos. En realidad es bastante simple. Ahora, antes de ir e intentar implementar esto, comprenda que el servidor DEBE verificar este archivo, porque el filtrado de JavaScript y HTML no es seguro en los casos en que alguien altera el archivo .js o incluso el HTML. No incluyo todo el guión real por el simple hecho de que disfruto ver a otros implementar los conceptos usando una mente creativa, pero estos son los pasos que he dado que parecen funcionar hasta que encuentre una mejor respuesta:

Crea un objeto js que encuentre la entrada y la maneje.

Llamar a una función, como OnClientUploadComplete para el control AsyncFileUpload de AjaxControlToolKit.

Dentro de esta función, declare una variable booleana: bIsAccepted (establecido en falso) y string sFileName (después de obtener el nombre de archivo de los argumentos).

En una declaración if..else,

if(sFilename.indexOf(".(acceptedExtension1)") || 
    sFileName.indexOf(".(AcceptedExtension2)")) 
{ 
    bIsAccepted = true; 
} 
else 
{ 
    bIsAccepted = false; 
} 

continuación

if(bIsAccepted) 
{ 
//Process Data 
} 

En el servidor, la creación de una lista de extensiones de archivo aceptados y bucle a través de procesamiento y de manera similar hará que el proceso de cohesión y consistente, permitiendo efectivamente que la IU y el código subyacente filtren los tipos de archivos en casi todas las situaciones.

Dado que esto puede omitirse cambiando el nombre para que tenga una extensión de archivo diferente como parte del nombre, el tipo de mimo también se debe verificar antes de enviarlo al servidor para su posterior procesamiento.

  [http://www.webmaster-toolkit.com/mime-types.shtml][1] 

Hope this helps!

+2

(1) Sugerencia: en lugar de hacer un '.indexOf (cada extensión codificada)', tome el valor del atributo 'accept' del control de entrada, divídalo por', \ s * ', y compruebe cada miembro del matriz que recibe de vuelta. En ese punto, al menos has implementado el comportamiento de filtrado de 'accept' (incluso si no puedes simular la UI). – cHao

+0

(2) En el lado del cliente, los tipos MIME no son mucho más confiables que las extensiones: es poco probable que el navegador abra el archivo y verifique los números mágicos y cosas por el estilo. Se basa en lo que el sistema informa como el tipo MIME y/o en sus propias extensiones de extensión internas <-->. – cHao

-3

Usando MVC podemos restringir carga para comprimir archivos sólo

.HtmlAttributes(new { accept = ".zip*" }) 
1

Se puede utilizar JavaScript. Tenga en cuenta que el gran problema al hacer esto con JavaScript es restablecer el archivo de entrada. Bueno, esto restringe sólo a JPG (para otros formatos, tendrá que cambiar el mime type y la magic number):

<form id="form-id"> 
    <input type="file" id="input-id" accept="image/jpeg"/> 
</form> 

<script type="text/javascript"> 
    $(function(){ 
     $("#input-id").on('change', function(event) { 
      var file = event.target.files[0]; 
      if(file.size>=2*1024*1024) { 
       alert("JPG images of maximum 2MB"); 
       $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form. 
       return; 
      } 

      if(!file.type.match('image/jp.*')) { 
       alert("only JPG images"); 
       $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form. 
       return; 
      } 

      var fileReader = new FileReader(); 
      fileReader.onload = function(e) { 
       var int32View = new Uint8Array(e.target.result); 
       //verify the magic number 
       // for JPG is 0xFF 0xD8 0xFF 0xE0 (see https://en.wikipedia.org/wiki/List_of_file_signatures) 
       if(int32View.length>4 && int32View[0]==0xFF && int32View[1]==0xD8 && int32View[2]==0xFF && int32View[3]==0xE0) { 
        alert("ok!"); 
       } else { 
        alert("only valid JPG images"); 
        $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form. 
        return; 
       } 
      }; 
      fileReader.readAsArrayBuffer(file); 
     }); 
    }); 
</script> 

, tenga en cuenta que esto fue probado en las últimas versiones de Firefox y Chrome, y en IExplore 10.

For a complete list of mime types see Wikipedia.

For a complete list of magic number see Wikipedia.

Cuestiones relacionadas