Проверка расширения файла перед загрузкой файла

92

Я загружаю изображения в сервлет. Проверка того, является ли загруженный файл изображением, выполняется только на стороне сервера путем проверки магических чисел в заголовке файла. Есть ли способ проверить расширения на стороне клиента перед отправкой формы в сервлет? Как только я нажимаю Enter, начинается загрузка.

Я использую Javascript и jQuery на стороне клиента.

Обновление: я, наконец, закончил проверку на стороне сервера, которая читает байты и отклоняет загрузку, если это не изображение.


источник
2
Вы используете Uploadify, как было предложено в одном из ваших предыдущих вопросов, верно?
BalusC
Нет, он останавливается между 50-96. Много раз пробовал с разными входами. И в то время я тоже очень спешил с решением. Итак, я попробовал простое jquery.ProgressBar.js. Работает, отлично. ### Итак, могу ли я проверить с помощью uploadify !!!
Разве мы не можем просто использовать атрибут accept во входном теге, чтобы убедиться, что пользователь выбирает файл указанного формата?
AnonSar

Ответы:

118

Можно проверить только расширение файла, но пользователь может легко переименовать virus.exe в virus.jpg и «пройти» проверку.

Вот код для проверки расширения файла и прерывания, если он не соответствует одному из допустимых расширений: (выберите недопустимый файл и попробуйте отправить, чтобы увидеть предупреждение в действии)

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>

Обратите внимание, что код позволит пользователю отправлять сообщения, не выбирая файл ... если требуется, удалите строку if (sFileName.length > 0) {и связанную с ней закрывающую скобку. Код будет проверять любой файл, введенный в форму, независимо от его имени.

Это можно сделать с помощью jQuery меньшим количеством строк, но мне достаточно «сырого» JavaScript, и конечный результат будет таким же.

Если у вас больше файлов или вы хотите запускать проверку при изменении файла, а не только при отправке формы, используйте вместо этого такой код:

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

Это покажет предупреждение и сбросит ввод в случае недопустимого расширения файла.

Shadow Wizard делает прививку
источник
Я просто хотел бы добавить, что использование «onSubmit» вместо «onChange» обременительно, особенно если используется опция «несколько». Каждый файл следует проверять по мере его выбора, а не при публикации всей формы.
DevlshOne
@DevlshОдна интересная идея, я также упомяну об этом в своем посте. Благодаря!
Shadow Wizard делает
Большое спасибо за этот код @Shadow Wizard, он мне очень помог!
Анаит Казарян
1
@garryman терпит неудачу, как? Вопрос здесь не упоминает, что файл требуется. Если в вашем случае файл является обязательным полем, вы можете переместить строку var blnValid = false;выше цикла через arrInputs, а затем после цикла проверьте переменную blnValid: если true, позвольте форме отправить, в противном случае покажите предупреждение о том, что файл необходим.
Shadow Wizard делает
проверьте мой ответ ниже
Divyesh Jani
75

Ни один из существующих ответов не казался достаточно компактным для простоты запроса. Проверить, имеет ли данное поле ввода файла расширение из набора, можно выполнить следующим образом:

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

Так пример использования может быть (где uploadэто idиз входного файла):

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

Или как плагин jQuery:

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

Пример использования:

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

Это .replace(/\./g, '\\.')нужно для экранирования точки для регулярного выражения, чтобы можно было передавать базовые расширения без точек, соответствующих любому символу.

В них нет проверки ошибок, чтобы они оставались короткими, предположительно, если вы их используете, вы сначала убедитесь, что ввод существует, а массив расширений действителен!

Орблинг
источник
10
Ницца. Обратите внимание, что в этих сценариях учитывается регистр. Чтобы решить эту проблему, вам нужно датьRexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);
Тедд Хансен
2
Немного сложно читать, но это означает добавление , "i"после конца регулярного выражения string ( )$'). Это добавит поддержку любого регистра в расширении имени файла (.jpg, .JPG, .Jpg и т. Д.)
Тедд Хансен,
Спасибо, Тедд, было бы лучше иметь сопоставление без учета регистра.
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
Спасибо, очень просто и чисто.
Th3_hide
если вы нажмете «Отмена», появится предупреждение.
PinoyStackOverflower
18

Я пришел сюда, потому что был уверен, что ни один из ответов здесь не был достаточно ... поэтическим:

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

Седрик Ипкисс
источник
Спасибо, это работает в Angular с небольшими изменениями, спасибо
skydev
у меня сработало хорошо, хотя перед тестированием следует удалить любые конечные пробелы в имени. +1
Роберто
9

проверьте, выбран ли файл или нет

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

проверьте расширение файла

  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

Мне нравится этот пример:

<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
источник
7

Используете ли вы input type = "file" для выбора файлов загрузки? если да, то почему бы не использовать атрибут accept?

<input type="file" name="myImage" accept="image/x-png,image/gif,image/jpeg" />
Rouven
источник
Этот! accept="image/*"в большинстве случаев это определенно самый разумный выбор.
Alberto T.
6

Если вам нужно протестировать удаленные URL-адреса в поле ввода, вы можете попробовать протестировать простое регулярное выражение с интересующими вас типами.

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

Это захватит все, что заканчивается на .gif, .jpg, .jpeg, .tiff или .png.

Я должен отметить, что некоторые популярные сайты, такие как Twitter, добавляют атрибут размера в конец своих изображений. Например, следующий тест не пройдет этот тест, даже если это допустимый тип изображения:

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

Из-за этого это не идеальное решение. Но это поможет вам пройти примерно 90% пути.

user3789031
источник
4

попробуйте это (работает для меня)

  
  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
источник
2

Еще один современный пример через 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

Вот более многоразовый способ, если вы используете jQuery

Библиотечная функция (не требует 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) }

Функция страницы (требуется jQuery (едва)):

$("[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

[Машинопись]

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

Вы можете использовать acceptатрибут, доступный для типов входных файлов. Документация по оформлению заказа MDN

Aditibtp
источник
2
При этом вы по-прежнему можете выбирать другие типы файлов
César León
@ CésarLeón Да. Пользователь может выбрать все файлы. Если вы хотите ограничить и это, вам необходимо выполнить ручную проверку. Проверьте другие ответы.
Madura Pradeep
1

Вот как это делается в jquery

$("#artifact_form").submit(function(){
    return ["jpg", "jpeg", "bmp", "gif", "png"].includes(/[^.]+$/.exec($("#artifact_file_name").val())[0])
  });
Jinja2Django
источник
1

Если вы хотите проверить кнопку просмотра и расширение файла, используйте этот код:

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
если вы хотите проверить кнопку просмотра и расширение файла, используйте этот код.
Аджай Кумар Гупта
1

Я думаю, лучше попробовать с mimetype, чем проверять расширение. Потому что иногда файлы могут существовать и без него, и они очень хорошо работают в системах Linux и Unix.

Итак, вы можете попробовать что-то вроде этого:

["image/jpeg", "image/png", "image/gif"].indexOf(file.type) > -1
Дананджая
источник
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
источник
3
Будет лучше, если вы напишете краткое описание своего ответа.
Roopendra 03
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

Вы можете создать массив, включающий необходимый тип файла, и использовать $ .inArray () в jQuery, чтобы проверить, существует ли тип файла в массиве.

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

мы можем проверить это при отправке или мы можем внести изменения в этот элемент управления

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;
    }
Дивеш Джани
источник
-1

На мой взгляд, это лучшее решение, которое намного короче других:

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

В этом случае функция вызывается из элемента управления Kendo Upload со следующими настройками:

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

Андрей
источник