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


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

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


Я просто хотел бы добавить, что использование «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>

7

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

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

Этот! 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% пути.


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>

     


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


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

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>

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")).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.