Convalida dell'estensione del file prima di caricare il file


90

Sto caricando immagini su un servlet. La convalida se il file caricato è un'immagine viene eseguita solo sul lato server, controllando i numeri magici nell'intestazione del file. C'è un modo per convalidare le estensioni lato client prima di inviare il modulo al servlet? Non appena premo invio, inizia il caricamento.

Sto usando Javascript e jQuery sul lato client.

Aggiornamento: alla fine sono stato ritrovato con la convalida lato server che legge i byte e rifiuta il caricamento se non è un'immagine.


2
Stai usando Uploadify come suggerito in una delle tue domande precedenti, giusto?
BalusC

No, si ferma tra 50 e 96. Ho provato molte volte con vari input. E all'epoca avevo anche fretta di trovare una soluzione. Quindi, ho provato a semplice jquery.ProgressBar.js. Funziona bene. ### Quindi, posso convalidare con uploadify !!!


Non possiamo semplicemente usare l'attributo di accettazione nel tag di input per assicurarci che l'utente selezioni il file del formato specificato?
AnonSar

Risposte:


117

È possibile controllare solo l'estensione del file, ma l'utente può facilmente rinominare virus.exe in virus.jpg e "passare" la convalida.

Per quel che vale, ecco il codice per controllare l'estensione del file e interromperla se non soddisfa una delle estensioni valide: (scegli il file non valido e prova a inviare per vedere l'avviso in azione)

var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];    
function Validate(oForm) {
    var arrInputs = oForm.getElementsByTagName("input");
    for (var i = 0; i < arrInputs.length; i++) {
        var oInput = arrInputs[i];
        if (oInput.type == "file") {
            var sFileName = oInput.value;
            if (sFileName.length > 0) {
                var blnValid = false;
                for (var j = 0; j < _validFileExtensions.length; j++) {
                    var sCurExtension = _validFileExtensions[j];
                    if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                        blnValid = true;
                        break;
                    }
                }
                
                if (!blnValid) {
                    alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
                    return false;
                }
            }
        }
    }
  
    return true;
}
<form onsubmit="return Validate(this);">
  File: <input type="file" name="my file" /><br />
  <input type="submit" value="Submit" />
</form>

Nota, il codice consentirà all'utente di inviare senza scegliere il file ... se necessario, rimuovere la riga if (sFileName.length > 0) {e la parentesi di chiusura associata. Il codice convaliderà qualsiasi input di file nel modulo, indipendentemente dal suo nome.

Questo può essere fatto con jQuery in meno righe, ma sono abbastanza a mio agio con JavaScript "grezzo" e il risultato finale è lo stesso.

Nel caso in cui tu abbia più file o desideri attivare il controllo dopo aver modificato il file e non solo nell'invio del modulo, utilizza invece tale codice:

var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];    
function ValidateSingleInput(oInput) {
    if (oInput.type == "file") {
        var sFileName = oInput.value;
         if (sFileName.length > 0) {
            var blnValid = false;
            for (var j = 0; j < _validFileExtensions.length; j++) {
                var sCurExtension = _validFileExtensions[j];
                if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                    blnValid = true;
                    break;
                }
            }
             
            if (!blnValid) {
                alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
                oInput.value = "";
                return false;
            }
        }
    }
    return true;
}
File 1: <input type="file" name="file1" onchange="ValidateSingleInput(this);" /><br />
File 2: <input type="file" name="file2" onchange="ValidateSingleInput(this);" /><br />
File 3: <input type="file" name="file3" onchange="ValidateSingleInput(this);" /><br />

Questo mostrerà un avviso e resetterà l'input in caso di estensione del file non valida.


Vorrei solo aggiungere che l'utilizzo di "onSubmit" invece di "onChange" è complicato, soprattutto se viene utilizzata l'opzione "multiple". Ogni file dovrebbe essere controllato come selezionato, non quando l'intero modulo viene pubblicato.
DevlshOne

@DevlshUna idea interessante, menzionerò anche questa nel post. Grazie!
Shadow Wizard is Ear For You

Grazie mille per questo codice @Shadow Wizard, mi ha davvero aiutato molto!
Anahit Ghazaryan

1
@garryman fallisce come? La domanda qui non menziona che il file è obbligatorio. Se nel tuo caso il file è un campo obbligatorio, puoi spostare la riga var blnValid = false;in modo che sia sopra il loop su arrInputs, quindi dopo il loop controlla la variabile blnValid: se true, lascia che il form invii, altrimenti mostra l'avviso che il file è richiesto.
Shadow Wizard is Ear For You

controlla la mia risposta qui sotto
Divyesh Jani

73

Nessuna delle risposte esistenti sembrava abbastanza compatta per la semplicità della richiesta. Il controllo se un determinato campo di input del file ha un'estensione da un set può essere eseguito come segue:

function hasExtension(inputID, exts) {
    var fileName = document.getElementById(inputID).value;
    return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$')).test(fileName);
}

Quindi l'utilizzo di esempio potrebbe essere (dov'è uploadl' idinput di un file):

if (!hasExtension('upload', ['.jpg', '.gif', '.png'])) {
    // ... block upload
}

O come plugin jQuery:

$.fn.hasExtension = function(exts) {
    return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$')).test($(this).val());
}

Utilizzo di esempio:

if (!$('#upload').hasExtension(['.jpg', '.png', '.gif'])) {
    // ... block upload
}

L' .replace(/\./g, '\\.')è lì per sfuggire il punto per l'espressione regolare in modo che le estensioni di base possono essere passati in senza i punti corrispondenti a qualsiasi carattere.

Non ci sono errori su questi per mantenerli brevi, presumibilmente se li usi ti assicurerai che l'input esista prima e che l'array delle estensioni sia valido!


10
Bello. Notare che questi script fanno distinzione tra maiuscole e minuscole. Per risolvere questo problema devi dareRexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);
Tedd Hansen

2
Un po 'difficile da leggere, ma ciò significa aggiungere , "i"dopo la fine della stringa regex ( )$'). Questo aggiungerà il supporto per qualsiasi case nell'estensione del nome file (.jpg, .JPG, .Jpg, ecc ...)
Tedd Hansen

Grazie, Tedd, sarebbe meglio avere una corrispondenza senza distinzione tra maiuscole e minuscole.
Orbling

39
$(function () {
    $('input[type=file]').change(function () {
        var val = $(this).val().toLowerCase(),
            regex = new RegExp("(.*?)\.(docx|doc|pdf|xml|bmp|ppt|xls)$");

        if (!(regex.test(val))) {
            $(this).val('');
            alert('Please select correct file format');
        }
    });
});

1
Grazie, molto semplice e pulito.
Th3_hide

se premi Annulla, verrà attivato un avviso.
PinoyStackOverflower

18

Sono venuto qui perché ero sicuro che nessuna delle risposte qui fosse abbastanza ... poetica:

function checkextension() {
  var file = document.querySelector("#fUpload");
  if ( /\.(jpe?g|png|gif)$/i.test(file.files[0].name) === false ) { alert("not an image!"); }
}
<input type="file" id="fUpload" onchange="checkextension()"/>


Grazie, funziona in Angular con poche modifiche, grazie
skydev

ha funzionato bene per me, anche se è necessario eliminare gli spazi finali dal nome prima di eseguire il test. +1
Roberto

9

controlla se il file è selezionato o meno

       if (document.myform.elements["filefield"].value == "")
          {
             alert("You forgot to attach file!");
             document.myform.elements["filefield"].focus();
             return false;  
         }

controlla l'estensione del file

  var res_field = document.myform.elements["filefield"].value;   
  var extension = res_field.substr(res_field.lastIndexOf('.') + 1).toLowerCase();
  var allowedExtensions = ['doc', 'docx', 'txt', 'pdf', 'rtf'];
  if (res_field.length > 0)
     {
          if (allowedExtensions.indexOf(extension) === -1) 
             {
               alert('Invalid file Format. Only ' + allowedExtensions.join(', ') + ' are allowed.');
               return false;
             }
    }

8

Mi piace questo esempio:

<asp:FileUpload ID="fpImages" runat="server" title="maximum file size 1 MB or less" onChange="return validateFileExtension(this)" />

<script language="javascript" type="text/javascript">
    function ValidateFileUpload(Source, args) {
        var fuData = document.getElementById('<%= fpImages.ClientID %>');
        var FileUploadPath = fuData.value;

        if (FileUploadPath == '') {
            // There is no file selected 
            args.IsValid = false;
        }
        else {
            var Extension = FileUploadPath.substring(FileUploadPath.lastIndexOf('.') + 1).toLowerCase();
            if (Extension == "gif" || Extension == "png" || Extension == "bmp" || Extension == "jpeg") {
                args.IsValid = true; // Valid file type
                FileUploadPath == '';
            }
            else {
                args.IsValid = false; // Not valid file type
            }
        }
    }
</script>

7

Usi il tipo di input = "file" per scegliere i file di caricamento? in tal caso, perché non utilizzare l'attributo accept?

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

Questo! accept="image/*"è sicuramente la scelta più intelligente nella maggior parte dei casi.
Alberto T.

6

Se hai bisogno di testare gli URL remoti in un campo di input, puoi provare a testare una semplice regex con i tipi che ti interessano.

$input_field = $('.js-input-field-class');

if ( !(/\.(gif|jpg|jpeg|tiff|png)$/i).test( $input_field.val() )) {
  $('.error-message').text('This URL is not a valid image type. Please use a url with the known image types gif, jpg, jpeg, tiff or png.');
  return false;
}

Questo catturerà tutto ciò che termina con .gif, .jpg, .jpeg, .tiff o .png

Dovrei notare che alcuni siti popolari come Twitter aggiungono un attributo size alla fine delle loro immagini. Ad esempio, quanto segue fallirebbe questo test anche se è un tipo di immagine valido:

https://pbs.twimg.com/media/BrTuXT5CUAAtkZM.jpg:large

Per questo motivo, questa non è una soluzione perfetta. Ma ti porterà a circa il 90% del percorso.


4

prova questo (funziona per me)

  
  function validate(){
  var file= form.file.value;
       var reg = /(.*?)\.(jpg|bmp|jpeg|png)$/;
       if(!file.match(reg))
       {
    	   alert("Invalid File");
    	   return false;
       }
       }
<form name="form">
<input type="file" name="file"/>
<input type="submit" onClick="return validate();"/>
</form>

     


2

Un altro esempio al giorno d'oggi tramite Array.prototype.some () .

function isImage(icon) {
  const ext = ['.jpg', '.jpeg', '.bmp', '.gif', '.png', '.svg'];
  return ext.some(el => icon.endsWith(el));
}

console.log(isImage('questions_4234589.png'));
console.log(isImage('questions_4234589.doc'));


1

Ecco un modo più riutilizzabile, assumendo che tu usi jQuery

Funzione libreria (non richiede jQuery):

function stringEndsWithValidExtension(stringToCheck, acceptableExtensionsArray, required) {
    if (required == false && stringToCheck.length == 0) { return true; }
    for (var i = 0; i < acceptableExtensionsArray.length; i++) {
        if (stringToCheck.toLowerCase().endsWith(acceptableExtensionsArray[i].toLowerCase())) { return true; }
    }
    return false;
}


String.prototype.startsWith = function (str) { return (this.match("^" + str) == str) }

String.prototype.endsWith = function (str) { return (this.match(str + "$") == str) }

Funzione pagina (richiede jQuery (a malapena)):

$("[id*='btnSaveForm']").click(function () {
    if (!stringEndsWithValidExtension($("[id*='fileUploader']").val(), [".png", ".jpeg", ".jpg", ".bmp"], false)) {
        alert("Photo only allows file types of PNG, JPG and BMP.");
        return false;
    }
    return true;
});

1

[Dattiloscritto]

uploadFileAcceptFormats: string[] = ['image/jpeg', 'image/gif', 'image/png', 'image/svg+xml'];

// if you find the element type in the allowed types array, then read the file
isAccepted = this.uploadFileAcceptFormats.find(val => {
    return val === uploadedFileType;
});

1

È possibile utilizzare l' acceptattributo disponibile per i tipi di file di input. Controlla la documentazione MDN


2
Con questo puoi ancora selezionare altri tipi di file
César León

@ CésarLeón Sì. L'utente ha la possibilità di selezionare tutti i file. Se vuoi limitare anche questo, devi eseguire la convalida manuale. Controlla altre risposte.
Madura Pradeep

1

Ecco come viene fatto in jquery

$("#artifact_form").submit(function(){
    return ["jpg", "jpeg", "bmp", "gif", "png"].includes(/[^.]+$/.exec($("#artifact_file_name").val())[0])
  });

1

Quando si desidera convalidare il pulsante Sfoglia e l'estensione del file, utilizzare questo codice:

function fileValidate(){ 
var docVal=document.forms[0].fileUploaded.value;
var extension = docVal.substring(docVal.lastIndexOf(".")+1,docVal.length);
if(extension.toLowerCase() != 'pdf')
alert("Please enter file  in .pdf extension ");

return false;
}

1
quando vuoi convalidare il pulsante Sfoglia e l'estensione del file, usa questo codice.
Ajay Kumar Gupta

0
<script type="text/javascript">

        function file_upload() {
            var imgpath = document.getElementById("<%=FileUpload1.ClientID %>").value;
            if (imgpath == "") {
                alert("Upload your Photo...");
                document.file.word.focus();
                return false;
            }
            else {
                // code to get File Extension..

                var arr1 = new Array;
                arr1 = imgpath.split("\\");
                var len = arr1.length;
                var img1 = arr1[len - 1];
                var filext = img1.substring(img1.lastIndexOf(".") + 1);
                // Checking Extension
                if (filext == "bmp" || filext == "gif" || filext == "png" || filext == "jpg" || filext == "jpeg" ) {
                    alert("Successfully Uploaded...")
                    return false;
                }
                else {
                    alert("Upload Photo with Extension ' bmp , gif, png , jpg , jpeg '");
                    document.form.word.focus();
                    return false;
                }
            }
        }

        function Doc_upload() {
            var imgpath = document.getElementById("<%=FileUpload2.ClientID %>").value;
            if (imgpath == "") {
                alert("Upload Agreement...");
                document.file.word.focus();
                return false;
            }
            else {
                // code to get File Extension..

                var arr1 = new Array;
                arr1 = imgpath.split("\\");
                var len = arr1.length;
                var img1 = arr1[len - 1];
                var filext = img1.substring(img1.lastIndexOf(".") + 1);
                // Checking Extension
                if (filext == "txt" || filext == "pdf" || filext == "doc") {
                    alert("Successfully Uploaded...")
                    return false;
                }
                else {
                    alert("Upload File with Extension ' txt , pdf , doc '");
                    document.form.word.focus();
                    return false;
                }
            }
        }
</script>

3
Sarebbe meglio se scrivessi una breve descrizione della tua risposta.
Roopendra

0

var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];    
function ValidateSingleInput(oInput) {
    if (oInput.type == "file") {
        var sFileName = oInput.value;
         if (sFileName.length > 0) {
            var blnValid = false;
            for (var j = 0; j < _validFileExtensions.length; j++) {
                var sCurExtension = _validFileExtensions[j];
                if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                    blnValid = true;
                    break;
                }
            }
             
            if (!blnValid) {
                alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
                oInput.value = "";
                return false;
            }
        }
    }
    return true;
}
File 1: <input type="file" name="file1" onchange="ValidateSingleInput(this);" /><br />
File 2: <input type="file" name="file2" onchange="ValidateSingleInput(this);" /><br />
File 3: <input type="file" name="file3" onchange="ValidateSingleInput(this);" /><br />


0

È possibile creare un array che includa il tipo di file necessario e utilizzare $ .inArray () in jQuery per verificare se il tipo di file esiste in array.

var imageType = ['jpeg', 'jpg', 'png', 'gif', 'bmp'];  

// Given that file is a file object and file.type is string 
// like "image/jpeg", "image/png", or "image/gif" and so on...

if (-1 == $.inArray(file.type.split('/')[1], imageType)) {
  console.log('Not an image type');
}

0

possiamo verificarlo al momento dell'invio o possiamo apportare modifiche all'evento di quel controllo

var fileInput = document.getElementById('file');
    var filePath = fileInput.value;
    var allowedExtensions = /(\.jpeg|\.JPEG|\.gif|\.GIF|\.png|\.PNG)$/;
    if (filePath != "" && !allowedExtensions.exec(filePath)) {
    alert('Invalid file extention pleasse select another file');
    fileInput.value = '';
    return false;
    }

0

Penso sia meglio provare con il tipo MIME piuttosto che controllare l'estensione. Perché, a volte i file possono esistere senza di esso e funzionano molto bene nei sistemi Linux e Unix.

Quindi, puoi provare qualcosa del genere:

["image/jpeg", "image/png", "image/gif"].indexOf(file.type) > -1

-1

Questa è la soluzione migliore secondo me, che è di gran lunga molto più breve delle altre:

function OnSelect(e) {
    var acceptedFiles = [".jpg", ".jpeg", ".png", ".gif"];
    var isAcceptedImageFormat = ($.inArray(e.files[0].extension, acceptedFiles)) != -1;

    if (!isAcceptedImageFormat) {
        $('#warningMessage').show();
    }
    else {
        $('#warningMessage').hide();
    }
}

In questo caso, la funzione viene chiamata da un controllo Kendo Upload con questa impostazione:

.Events(e => e.Select("OnSelect")).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.