Cómo hacer que el tipo de entrada = archivo debe aceptar solo pdf y xls

102

solía <input type= "file" name="Upload" >

Ahora me gustaría restringir esto aceptando solo archivos .pdf y .xls.

Cuando hago clic en el botón enviar, debería validar esto.

Y cuando hago clic en los archivos (PDF / XLS) en la página web, debería abrirse automáticamente.

¿Alguien podría dar algunos ejemplos para esto?

Manikandan
fuente

Respuestas:

179

Puede hacerlo usando el atributo accepty agregándole tipos mime permitidos. Pero no todos los navegadores respetan ese atributo y podría eliminarse fácilmente mediante algún inspector de código. Entonces, en cualquier caso, debe verificar el tipo de archivo en el lado del servidor (su segunda pregunta).

Ejemplo:

<input type="file" name="upload" accept="application/pdf,application/vnd.ms-excel" />

A su tercera pregunta "Y cuando hago clic en los archivos (PDF / XLS) en la página web, debería abrirse automáticamente":

No puedes lograr eso. El usuario establece cómo se abre un PDF o XLS en la máquina cliente.

Feeela
fuente
Hola feeela Cuando suba los archivos, se almacenarán en el servidor. Escuché que es posible mediante las funciones de JavaScript abrir archivos .pdf y .xls haciendo clic en los archivos en el navegador ...
Manikandan
Eso es ! Ambos lados cliente y servidor explicados. Gran respuesta
3
si enumera todos los archivos en el cuadro de selección. aún puede cargar cualquier archivo.
rüff0
59

puedes usar esto:

HTML

<input name="userfile" type="file" accept="application/pdf, application/vnd.ms-excel" />

solo apoyo. PDF y. Archivos XLS

Radamés E. Hernández
fuente
14

Desafortunadamente, no existe una forma garantizada de hacerlo en el momento de la selección.

Algunos navegadores admiten el acceptatributo para inputetiquetas. Este es un buen comienzo, pero no se puede confiar completamente en él.

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

Puede utilizar ay cfinputejecutar una validación para comprobar la extensión del archivo en el momento del envío, pero no el tipo mime. Esto es mejor, pero aún no infalible. Los archivos en OSX a menudo no tienen extensiones de archivo o los usuarios podrían etiquetar incorrectamente los tipos de archivo de forma maliciosa.

ColdFusion cffilepuede verificar el tipo de mime usando la contentTypepropiedad del resultado ( cffile.contentType), pero eso solo se puede hacer después de la carga. Esta es su mejor opción, pero aún no es 100% segura ya que los mimos podrían estar equivocados.

Joe C
fuente
3
Por favor, nunca verifique un archivo basado en la extensión. ¿Qué pasa con un ejecutable llamado lolcat.jpg?
feeela
1
Creo que lo que phantom42 está tratando de decir aquí es que debe verificar la extensión y el tipo MIME en el servidor. El acceptatributo en la inputetiqueta se puede agregar pero no es 100% efectivo.
Chris Peters
Estoy 100% de acuerdo. No se puede confiar en él, pero lo encuentro bien como primera línea de defensa junto con cffile.contenttype.
Joe C
Hola, Phantom Como dijiste, esta aceptación solo funciona en Chrome, no en IE. ¿Hay alguna otra forma de hacer esto que sea compatible con todos los navegadores
Manikandan
Lamentablemente no; por eso dije que no se puede confiar en él y que debe usarse junto con los otros métodos si es que lo usa.
Joe C
4

Puedes usar JavaScript. Tenga en cuenta que el gran problema de hacer esto con JavaScript es restablecer el archivo de entrada. Bueno, esto se restringe solo a JPG (para PDF tendrás que cambiar el tipo de mímica y el número mágico ):

<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 se probó en las últimas versiones de Firefox y Chrome, y en IExplore 10.

Para obtener una lista completa de tipos de mímica, consulte Wikipedia .

Para obtener una lista completa de números mágicos, consulte Wikipedia .

lmiguelmh
fuente
4

Puedes intentar seguir el camino

<input type= "file" name="Upload" accept = "application/pdf,.csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">

O (en asp.net mvc)

@Html.TextBoxFor(x => x.FileName, new { @id = "doc", @type = "file", @accept = "application/pdf,.csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" })
Prashant Odhavani
fuente
2

Filtraría el lado del servidor de archivos, porque hay herramientas, como Live HTTP Headers en Firefox, que permitirían cargar cualquier archivo, incluido un shell. La gente podría piratear tu sitio. Hágalo en el sitio del servidor, para estar seguro.

Alexandre Hitchcox
fuente
¡Esto es muy cierto! Por favor, no ignore este consejo
Rodney Salcedo
1

Si bien este ejemplo en particular es para la carga de varios archivos, brinda la información general que uno necesita:

https://developer.mozilla.org/en-US/docs/DOM/File.type

En cuanto a actuar sobre un archivo en / download /, esta no es una pregunta de Javascript, sino más bien una configuración del servidor. Si un usuario no tiene algo instalado para abrir archivos PDF o XLS, su única opción será descargarlos.

Jeremy J Starcher
fuente
0

Si desea que el control de carga de archivos limite los tipos de archivos que el usuario puede cargar con un clic, este es el camino.

<script type="text/JavaScript">
<!-- Begin
function TestFileType( fileName, fileTypes ) {
if (!fileName) return;

dots = fileName.split(".")
//get the part AFTER the LAST period.
fileType = "." + dots[dots.length-1];

return (fileTypes.join(".").indexOf(fileType) != -1) ?
alert('That file is OK!') : 
alert("Please only upload files that end in types: \n\n" + (fileTypes.join(" .")) + "\n\nPlease select a new file and try again.");
}
// -->
</script>

Luego puede llamar a la función desde un evento como el onClick del botón anterior, que se ve así:

onClick = "TestFileType (this.form.uploadfile.value, ['gif', 'jpg', 'png', 'jpeg']);"

Puede cambiar esto a: PDFyXLS

Puedes verlo implementado aquí: Demo

Vishal Suthar
fuente
Gracias Vishal Suthar. Creo que esta lógica seguramente me ayudará a seguir adelante.
Manikandan
Es un placer ... Seguro que ayudará, pero aún no hay
voto a favor
Todavía tengo una duda más. Intenté restringir los archivos (solo PDF y Xls.xlsx) en input type = file. Pero funciona bien en Google Chrome ... Pero no puedo hacer esto en IE. ¿Existe alguna solución para restringir los archivos en IE? Si es así, por favor, hágame ir de la manera correcta.
Manikandan
Acabo de comprobar ( codestore.net/store.nsf/unid/DOMM-4Q8H9E ) en IE y funciona bien .. @ Manikandan
Vishal Suthar
En comparación con el acceptatributo-, este método no reduce el contenido de la carpeta a los tipos de archivo seleccionados al seleccionar un archivo en la máquina local.
feeela
0

Prueba este: -

              <MyTextField
                id="originalFileName"
                type="file"
                inputProps={{ accept: '.xlsx, .xls, .pdf' }}
                required
                label="Document"
                name="originalFileName"
                onChange={e => this.handleFileRead(e)}
                size="small"
                variant="standard"
              />
Ankit Kumar Rajpoot
fuente