上传文件前验证文件扩展名

IT技术 javascript jquery validation file-upload
2021-02-02 05:20:44

我正在将图像上传到 servlet。通过检查文件头中的幻数来验证上传的文件是否为图像仅在服务器端完成。在将表单提交给 servlet 之前,有什么方法可以验证客户端的扩展吗?我一回车就开始上传。

我在客户端使用 Javascript 和 jQuery。

更新: 我终于结束了服务器端验证,它读取字节并拒绝上传,如果它不是图像。

6个回答

可以只检查文件扩展名,但用户可以轻松地将virus.exe 重命名为virus.jpg 并“通过”验证。

对于它的value,这里是检查文件扩展名并在不符合有效扩展名之一时中止的代码:(选择无效文件并尝试提交以查看警报)

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”很麻烦——尤其是在使用“multiple”选项的情况下。每个文件都应在选择时进行检查,而不是在发布整个表单时进行检查。
2021-03-16 05:20:44
检查我的以下答案
2021-03-20 05:20:44
@garryman 怎么会失败?这里的问题没有提到文件是必需的。如果在您的情况下该文件是必填字段,您可以将该行移动var blnValid = false;到 arrInputs 上的循环上方,然后在循环之后检查变量 blnValid:如果为真,则让表单提交,否则显示需要该文件的警报。
2021-03-23 05:20:44
@DevlshOne 有趣的想法,也会在帖子中提到这一点。谢谢!
2021-03-28 05:20:44
非常感谢您提供此代码 @Shadow Wizard。它对我帮助很大!
2021-04-09 05:20:44

对于请求的简单性而言,现有的答案似乎都不够紧凑。检查给定的文件输入字段是否具有一组扩展名可以按如下方式完成:

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

因此,例如使用可能(这里uploadid一个文件输入的):

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, '\\.')有逃脱的正则表达式的点,使基础扩展可以在没有匹配任何字符的点进行传递。

没有对这些进行错误检查以保持它们的简短,大概如果您使用它们,您将确保输入首先存在并且扩展数组有效!

有点难以阅读,但这意味着, "i"在正则表达式字符串 ( )$')结尾之后添加这将添加对文件扩展名中的任何大小写的支持(.jpg、.JPG、.Jpg 等...)
2021-03-23 05:20:44
谢谢你,泰德,不区分大小写的匹配会更好。
2021-04-06 05:20:44
好的。请注意,这些脚本区分大小写。要解决这个问题,你需要给RexExp the "i" modifier, for example: return (new RegExp('(' + exts.join('|').replace(/\./g, '\\.') + ')$', "i")).test(fileName);
2021-04-09 05:20:44
$(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');
        }
    });
});
如果您有一个“文件”对象,请file.name改用 val():var val = $(file.name).toLowerCase(), ...
2021-03-28 05:20:44
如果您按取消,它将触发警报。
2021-03-30 05:20:44
谢谢,非常简单和干净。
2021-03-31 05:20:44

我来这里是因为我确信这里的答案都不是很......诗意的:

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

对我来说效果很好,尽管在测试之前应该修剪名称中的任何尾随空格。+1
2021-03-28 05:20:44
感谢这在 Angular 中几乎没有修改,谢谢
2021-03-29 05:20:44

检查是否选择了文件

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