Weryfikacja rozszerzenia pliku przed przesłaniem pliku

90

Przesyłam obrazy do serwletu. Sprawdzanie, czy przesłany plik jest obrazem, odbywa się tylko po stronie serwera, sprawdzając magiczne liczby w nagłówku pliku. Czy istnieje sposób sprawdzenia poprawności rozszerzeń po stronie klienta przed przesłaniem formularza do serwletu? Jak tylko kliknę Enter, rozpocznie się przesyłanie.

Używam Javascript i jQuery po stronie klienta.

Aktualizacja: w końcu skończyłem z walidacją po stronie serwera, która odczytuje bajty i odrzuca przesyłanie, jeśli nie jest to obraz.


źródło
2
Używasz Uploadify, jak sugerowano w jednym z poprzednich pytań, prawda?
BalusC
Nie, zatrzymuje się między 50 a 96. Próbowałem wiele razy z różnymi wejściami. W tamtym czasie również spieszyłem się z rozwiązaniem. Więc spróbowałem prostego jquery.ProgressBar.js. To działa dobrze. ### Czy mogę zweryfikować za pomocą uploadify !!!
Czy nie możemy po prostu użyć atrybutu accept w tagu wejściowym, aby upewnić się, że użytkownik wybierze plik o określonym formacie?
AnonSar

Odpowiedzi:

117

Możliwe jest sprawdzenie tylko rozszerzenia pliku, ale użytkownik może łatwo zmienić nazwę wirusa virus.exe na virus.jpg i „przejść” walidację.

Co jest warte, oto kod, aby sprawdzić rozszerzenie pliku i przerwać, jeśli nie spełnia jednego z ważnych rozszerzeń: (wybierz nieprawidłowy plik i spróbuj przesłać, aby zobaczyć alert w akcji)

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>

Uwaga, kod pozwoli użytkownikowi na wysyłanie bez wybierania pliku ... jeśli jest to wymagane, usuń wiersz if (sFileName.length > 0) {i skojarzony z nim nawias zamykający. Kod zweryfikuje każdy plik wejściowy w formularzu, niezależnie od jego nazwy.

Można to zrobić za pomocą jQuery w mniejszej liczbie wierszy, ale czuję się wystarczająco dobrze z „surowym” JavaScriptem, a ostateczny wynik jest taki sam.

Jeśli masz więcej plików lub chcesz uruchomić sprawdzanie przy zmianie pliku, a nie tylko przy przesyłaniu formularza, użyj zamiast tego takiego kodu:

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 />

Spowoduje to wyświetlenie ostrzeżenia i zresetowanie danych wejściowych w przypadku nieprawidłowego rozszerzenia pliku.

Czarodziej cienia to ucho dla Ciebie
źródło
Chciałbym tylko dodać, że używanie „onSubmit” zamiast „onChange” jest uciążliwe - zwłaszcza jeśli używana jest opcja „wiele”. Każdy plik powinien być zaznaczony tak, jak został wybrany, a nie po wysłaniu całego formularza.
DevlshOne
@DevlshOne ciekawy pomysł, o tym również wspomnę w poście. Dzięki!
Shadow Wizard is Ear For You
Bardzo dziękuję za ten kod @Shadow Wizard. Naprawdę bardzo mi pomógł!
Anahit Ghazaryan
1
Jak zawodzi @garryman? Pytanie tutaj nie wspomina, że ​​plik jest wymagany. Jeśli w twoim przypadku plik jest polem wymaganym, możesz przesunąć linię tak, var blnValid = false;aby znajdowała się nad pętlą przez arrInputs, a następnie po pętli sprawdź zmienną blnValid: jeśli prawda, pozwól formularzowi przesłać, w przeciwnym razie pokaż ostrzeżenie, że plik jest wymagany.
Shadow Wizard is Ear For You
sprawdź moją poniższą odpowiedź
Divyesh Jani
73

Żadna z istniejących odpowiedzi nie wydawała się wystarczająco zwięzła dla prostoty żądania. Sprawdzenie, czy dane pole wejściowe pliku ma rozszerzenie z zestawu można wykonać w następujący sposób:

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

Tak więc przykładowe użycie może wyglądać tak (gdzie uploadjest idwejście pliku):

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

Lub jako wtyczka jQuery:

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

Przykładowe użycie:

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

.replace(/\./g, '\\.')Jest tam, aby uciec z kropka na regexp tak że podstawowe rozszerzenia mogą być przekazywane w bez kropek odpowiadających dowolny znak.

Nie ma na nich żadnego sprawdzania błędów, aby były krótkie, prawdopodobnie jeśli ich użyjesz, upewnisz się, że dane wejściowe istnieją jako pierwsze, a tablica rozszerzeń jest prawidłowa!

Orbling
źródło
10
Ładny. Zauważ, że te skrypty uwzględniają wielkość liter. Aby rozwiązać ten problem, musisz daćRexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);
Tedd Hansen
2
Trochę trudny do odczytania, ale oznacza to dodanie , "i"po końcu wyrażenia regularnego string ( )$'). To doda obsługę dowolnej wielkości liter w rozszerzeniu nazwy pliku (.jpg, .JPG, .Jpg, itd ...)
Tedd Hansen
Dziękuję Tedd, lepiej byłoby mieć dopasowywanie bez rozróżniania wielkości liter.
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');
        }
    });
});
Ashish Pathak
źródło
1
Dzięki, bardzo proste i czyste.
Th3_hide
jeśli naciśniesz anuluj, uruchomi się alert.
PinoyStackOverflower
18

Przyszedłem tutaj, ponieważ byłem pewien, że żadna z odpowiedzi nie była dość ... poetycka:

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()"/>

Cedric Ipkiss
źródło
Dzięki temu działa w Angular z niewielkimi modyfikacjami, dzięki
skydev
działało dobrze, chociaż przed testowaniem należy usunąć wszelkie spacje końcowe z nazwy. +1
Roberto
9

sprawdź, czy plik jest zaznaczony, czy nie

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

sprawdź rozszerzenie pliku

  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;
             }
    }
Rizwan Gill
źródło
8

Podoba mi się ten przykład:

<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>
kamal.shalabe
źródło
7

Czy używasz input type = "file", aby wybrać przesłane pliki? jeśli tak, dlaczego nie użyć atrybutu accept?

<input type="file" name="myImage" accept="image/x-png,image/gif,image/jpeg" />
Rouven
źródło
To! accept="image/*"w większości przypadków jest to zdecydowanie najmądrzejszy wybór.
Alberto T.
6

Jeśli chcesz przetestować zdalne adresy URL w polu wejściowym, możesz spróbować przetestować proste wyrażenie regularne z typami, które Cię interesują.

$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;
}

Spowoduje to przechwycenie wszystkiego, co kończy się na .gif, .jpg, .jpeg, .tiff lub .png

Powinienem zauważyć, że niektóre popularne witryny, takie jak Twitter, dodają atrybut rozmiaru na końcu swoich zdjęć. Na przykład poniższe testy nie przejdą tego testu, mimo że jest to prawidłowy typ obrazu:

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

Z tego powodu nie jest to idealne rozwiązanie. Ale to doprowadzi cię do około 90% drogi.

user3789031
źródło
4

spróbuj tego (działa dla mnie)

  
  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>

     

AlphaOne
źródło
2

Kolejny współczesny przykład za pośrednictwem 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'));

Penny Liu
źródło
1

Oto sposób bardziej wielokrotnego użytku, zakładając, że używasz jQuery

Funkcja biblioteki (nie wymaga 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) }

Funkcja strony (wymaga jQuery (ledwo)):

$("[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;
});
Micah B.
źródło
1

[Maszynopis]

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;
});
mkupiniak
źródło
1

Możesz użyć acceptatrybutu dostępnego dla typów plików wejściowych. Dokumentacja Checkout MDN

Aditibtp
źródło
2
Dzięki temu możesz nadal wybierać inne typy plików
César León
@ CésarLeón Yes. Użytkownik ma możliwość wyboru wszystkich plików. Jeśli chcesz to również ograniczyć, musisz przeprowadzić ręczną weryfikację. Sprawdź inne odpowiedzi.
Madura Pradeep
1

Tak to się robi w jquery

$("#artifact_form").submit(function(){
    return ["jpg", "jpeg", "bmp", "gif", "png"].includes(/[^.]+$/.exec($("#artifact_file_name").val())[0])
  });
Abhiyan Timilsina
źródło
1

Jeśli chcesz sprawdzić poprawność przycisku przeglądania i rozszerzenia pliku, użyj tego kodu:

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;
}
Ajay Kumar Gupta
źródło
1
jeśli chcesz sprawdzić poprawność przycisku przeglądania i rozszerzenia pliku, użyj tego kodu.
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>
user3060112
źródło
3
Byłoby lepiej, gdybyś napisał krótki opis swojej odpowiedzi.
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 />

francin
źródło
0

Możesz utworzyć tablicę zawierającą wymagany typ pliku i użyć $ .inArray () w jQuery, aby sprawdzić, czy typ pliku istnieje w tablicy.

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');
}
John Roca
źródło
0

możemy to sprawdzić po przesłaniu lub możemy wprowadzić zdarzenie zmiany tej kontroli

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;
    }
Divyesh Jani
źródło
0

Myślę, że lepiej spróbować z typem MIME niż sprawdzać rozszerzenie. Ponieważ czasami pliki mogą istnieć bez niego, a te działają bardzo dobrze w systemach linux i unix.

Możesz więc spróbować czegoś takiego:

["image/jpeg", "image/png", "image/gif"].indexOf(file.type) > -1
Dananjaya
źródło
-1

To moim zdaniem najlepsze rozwiązanie, które jest zdecydowanie krótsze od pozostałych:

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();
    }
}

W tym przypadku funkcja jest wywoływana z kontrolki Kendo Upload z tym ustawieniem:

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

Andrzej
źródło