Xác thực phần mở rộng tệp trước khi tải tệp lên


90

Tôi đang tải hình ảnh lên một servlet. Việc xác thực xem tệp đã tải lên có phải là hình ảnh hay không chỉ được thực hiện ở phía máy chủ, bằng cách kiểm tra các con số kỳ diệu trong tiêu đề tệp. Có cách nào để xác thực các tiện ích mở rộng ở phía máy khách trước khi gửi biểu mẫu tới servlet không? Ngay sau khi tôi nhấn enter, nó sẽ bắt đầu tải lên.

Tôi đang sử dụng Javascript và jQuery ở phía máy khách.

Cập nhật: Cuối cùng tôi đã kết thúc với xác thực phía máy chủ đọc byte và từ chối tải lên nếu nó không phải là hình ảnh.


2
Bạn đang sử dụng Uploadify như được đề xuất trong một trong những câu hỏi trước của bạn, phải không?
BalusC

Không, nó dừng trong khoảng 50-96. Đã thử nhiều lần với nhiều đầu vào khác nhau. Và, tôi cũng đang vội vàng tìm một giải pháp vào thời điểm đó. Vì vậy, tôi đã thử đơn giản jquery.ProgressBar.js. Nó hoạt động tốt. ### Vậy, tôi có thể xác thực bằng uploadify không !!!


Chúng ta không thể chỉ sử dụng thuộc tính accept trong thẻ đầu vào để đảm bảo rằng người dùng chọn tệp có định dạng được chỉ định?
AnonSar

Câu trả lời:


117

Chỉ có thể kiểm tra phần mở rộng tệp, nhưng người dùng có thể dễ dàng đổi tên virus.exe thành virus.jpg và "vượt qua" xác thực.

Đối với những gì nó đáng giá, đây là mã để kiểm tra phần mở rộng tệp và hủy bỏ nếu không đáp ứng một trong các phần mở rộng hợp lệ: (chọn tệp không hợp lệ và cố gắng gửi để xem cảnh báo đang hoạt động)

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>

Lưu ý, mã sẽ cho phép người dùng gửi mà không cần chọn tệp ... nếu nó được yêu cầu, hãy xóa dòng if (sFileName.length > 0) {và nó liên kết với dấu ngoặc đóng. Mã sẽ xác thực bất kỳ đầu vào tệp nào trong biểu mẫu, bất kể tên của nó.

Điều này có thể được thực hiện với jQuery trong ít dòng hơn, nhưng tôi đủ thoải mái với JavaScript "thô" và kết quả cuối cùng là như nhau.

Trong trường hợp bạn có nhiều tệp hơn hoặc muốn kích hoạt kiểm tra khi thay đổi tệp và không chỉ khi gửi biểu mẫu, hãy sử dụng mã như vậy để thay thế:

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

Điều này sẽ hiển thị cảnh báo và đặt lại đầu vào trong trường hợp phần mở rộng tệp không hợp lệ.


Tôi chỉ muốn nói thêm rằng việc sử dụng "onSubmit" thay vì "onChange" là rườm rà - đặc biệt nếu tùy chọn "nhiều" được sử dụng. Mỗi tệp nên được kiểm tra khi nó được chọn, không phải khi toàn bộ biểu mẫu được đăng.
DevlshMột

@DevlshMột ý tưởng thú vị, cũng sẽ đề cập đến vấn đề này trong bài đăng. Cảm ơn!
Shadow Wizard là Ear For You

Cảm ơn bạn rất nhiều vì mã này @Shadow Wizard. Nó thực sự đã giúp tôi rất nhiều!
Anahit Ghazaryan

1
@garryman không thành công như thế nào? Câu hỏi ở đây không đề cập đến tệp là bắt buộc. Nếu trong trường hợp của bạn, tệp là trường bắt buộc, bạn có thể di chuyển dòng var blnValid = false;lên phía trên vòng lặp qua arrInputs, sau đó sau vòng lặp, hãy kiểm tra biến blnValid: nếu đúng, hãy gửi biểu mẫu, nếu không, hãy hiển thị cảnh báo rằng tệp là bắt buộc.
Shadow Wizard là Ear For You

kiểm tra câu trả lời bên dưới của tôi
Divyesh Jani

73

Không có câu trả lời nào trong số các câu trả lời hiện có có vẻ khá nhỏ gọn để đáp ứng yêu cầu đơn giản. Việc kiểm tra xem trường nhập tệp nhất định có phần mở rộng từ một tập hợp hay không có thể được thực hiện như sau:

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

Vì vậy, ví dụ sử dụng có thể (trong đó uploadidcủa một tập tin đầu vào):

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

Hoặc như một plugin jQuery:

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

Ví dụ sử dụng:

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

.replace(/\./g, '\\.')đó để thoát khỏi dấu chấm cho regexp để các phần mở rộng cơ bản có thể được chuyển vào mà không có dấu chấm khớp với bất kỳ ký tự nào.

Không có lỗi khi kiểm tra những thứ này để giữ cho chúng ngắn gọn, có lẽ nếu bạn sử dụng chúng, bạn sẽ đảm bảo rằng đầu vào tồn tại trước tiên và mảng mở rộng hợp lệ!


10
Đẹp. Lưu ý rằng các tập lệnh này phân biệt chữ hoa chữ thường. Để giải quyết điều này, bạn cần phải cung cấpRexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);
Tedd Hansen

2
Hơi khó đọc, nhưng điều đó có nghĩa là thêm vào , "i"sau cuối chuỗi regex ( )$'). Điều này sẽ hỗ trợ thêm cho bất kỳ vỏ ở phần mở rộng tên file (.jpg, .JPG, .jpg, vv ...)
Tedd Hansen

Cảm ơn bạn, Tedd, sẽ tốt hơn nếu có kết hợp không phân biệt chữ hoa chữ thường.
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
Cảm ơn, rất đơn giản và sạch sẽ.
Th3_hide

nếu bạn nhấn hủy, nó sẽ kích hoạt một cảnh báo.
PinoyStackOverflower

18

Tôi đến đây vì tôi chắc chắn không có câu trả lời nào ở đây khá ... thơ mộng:

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


Nhờ công trình này trong góc với chút sửa đổi, nhờ
skydev

hoạt động tốt đối với tôi, mặc dù người ta nên cắt bỏ bất kỳ khoảng trống nào ở cuối tên trước khi thử nghiệm. +1
Roberto

9

kiểm tra xem tệp có được chọn hay không

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

kiểm tra phần mở rộng tệp

  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

Tôi thích ví dụ này:

<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

Bạn có sử dụng input type = "file" để chọn tệp tải lên không? nếu vậy, tại sao không sử dụng thuộc tính accept?

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

Điều này! accept="image/*"nó chắc chắn là sự lựa chọn thông minh nhất trong hầu hết các trường hợp.
Alberto T.

6

Nếu bạn cần kiểm tra các url từ xa trong một trường nhập liệu, bạn có thể thử kiểm tra một regex đơn giản với các loại mà bạn quan tâm.

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

Thao tác này sẽ ghi lại mọi thứ kết thúc bằng .gif, .jpg, .jpeg, .tiff hoặc .png

Tôi nên lưu ý rằng một số trang web phổ biến như Twitter thêm thuộc tính kích thước vào cuối hình ảnh của họ. Ví dụ: điều sau sẽ không thành công thử nghiệm này mặc dù đó là loại hình ảnh hợp lệ:

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

Do đó, đây không phải là một giải pháp hoàn hảo. Nhưng nó sẽ giúp bạn đi được khoảng 90% chặng đường.


4

thử cái này (Làm việc cho tôi)

  
  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

Một ví dụ khác ngày nay qua 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

Đây là một cách có thể tái sử dụng nhiều hơn, giả sử bạn sử dụng jQuery

Chức năng thư viện (không yêu cầu 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) }

Hàm trang (yêu cầu jQuery (hầu như không)):

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

[TypeScript]

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

Bạn có thể sử dụng acceptthuộc tính có sẵn cho các loại tệp đầu vào. Kiểm tra tài liệu MDN


2
Với điều này bạn vẫn có thể chọn các loại tập tin khác
César León

@ CésarLeón Vâng. Người dùng có tùy chọn để chọn tất cả các tệp. Nếu bạn cũng muốn hạn chế điều đó, bạn cần phải xác thực thủ công. Kiểm tra các câu trả lời khác.
Madura Pradeep

1

Đây là cách nó được thực hiện trong jquery

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

1

Khi bạn muốn xác thực nút duyệt và phần mở rộng tệp, hãy sử dụng mã này:

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
khi bạn muốn xác thực nút duyệt và phần mở rộng tệp, hãy sử dụng mã này.
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
Sẽ tốt hơn nếu bạn viết mô tả ngắn về câu trả lời của mình.
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

Bạn có thể tạo một mảng bao gồm loại tệp cần thiết và sử dụng $ .inArray () trong jQuery để kiểm tra xem loại tệp có tồn tại trong mảng hay không.

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

chúng tôi có thể kiểm tra nó khi gửi hoặc chúng tôi có thể thực hiện sự kiện thay đổi kiểm soát đó

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

Tôi nghĩ tốt hơn nên thử với mimetype hơn là kiểm tra tiện ích mở rộng. Bởi vì, đôi khi các tệp có thể tồn tại mà không có nó và những tệp đó đang hoạt động rất tốt trong hệ thống linux và unix.

Vì vậy, bạn có thể thử một cái gì đó như sau:

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

-1

Đây là giải pháp tốt nhất theo ý kiến ​​của tôi, nó ngắn hơn nhiều so với các giải pháp khác:

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

Trong trường hợp này, chức năng được gọi từ điều khiển Tải lên Kendo với cài đặt này:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.