如何验证 Javascript 中的 single/multiple 图像并在输入下方显示错误消息以防止默认提交?

How to validate an single/multiple image in Javascript and show error message below the input with prevent default submit?

实际上我有一个可以输入图像的表格。我想针对三种情况验证图像

  1. 扩展名应为 png、jpg
  2. 大小应小于 2048kb
  3. 小于 200px x 200px 被视为尺寸

我写了一个函数并解决了问题 1 和问题 2。为了解决问题 3,我在 onload 侦听器中使用图像 reader,当我单击它时,如果我删除 3,它也不能阻止提交,那么它工作正常! JS中有解决上述问题的方法吗?

下面是我的代码幻灯片。

function isImageValid(idName) {

    var fileUpload = document.getElementById(idName);
     var fileName = document.getElementById(idName).value;


    if (typeof (fileUpload.files) != "undefined") {
        for (var i=0; i<fileUpload.files.length;i++)
   {
    //    console.log(fileUpload.files[i]);
        var valid_dimension = 0;

       var reader = new FileReader();

        //Read the contents of Image File.
        reader.readAsDataURL(fileUpload.files[0]);
        reader.onload = function (e) {

        //Initiate the JavaScript Image object.
        var image = new Image();

        //Set the Base64 string return from FileReader as source.
        image.src = e.target.result;

        //Validate the File Height and Width.
        image.onload = function () {
            var height = this.height;
            var width = this.width;

            if (height>200||width>200) {

           valid_dimension =1;
            // alert("Height and Width must not exceed 200px.");
             return false;
            }
        //    alert("Uploaded image has valid Height and Width.");
             return true;
        };


        };
         var size = parseFloat(fileUpload.files[0].size / 1024).toFixed(2);
         var extension = fileName.split('.').pop();

       if( valid_dimension ==1||size>2048||(extension!='jpg'&&extension!='JPG'&&extension!='JPEG'&&extension!='jpeg'&&extension!='png'&&extension!='PNG'))
       return false;
       else
       return true;
   }



    } else {
       return false;
    }
}

并且,

    const form = document.getElementById('employee_form');
  form.addEventListener('submit', (e)=>{

var is_avatar_img_valid = isImageValid('avatar');
if(is_avatar_img_valid==false){

         e.preventDefault();
         document.getElementById("avatar").style.borderColor = "red";
         document.getElementById('avatar_validator_message').innerHTML = 'Invalid image';
       }
       else{
        document.getElementById("avatar").style.borderColor = "black";
        document.getElementById('avatar_validator_message').innerHTML = '';
      }
}

在您需要使用的表单事件列表中

e.preventDefault()

完整代码如下所示

const form = document.getElementById('employee_form');
form.addEventListener('submit', (e) => {
    e.preventDefault()

    var is_avatar_img_valid = isImageValid('avatar');
    if (is_avatar_img_valid == false) {

        e.preventDefault();
        document.getElementById("avatar").style.borderColor = "red";
        document.getElementById('avatar_validator_message').innerHTML = 'Invalid image';
    }
    else {
        document.getElementById("avatar").style.borderColor = "black";
        document.getElementById('avatar_validator_message').innerHTML = '';
    }
});

问题是 reader.onload 和 image.onload 函数本质上是异步的。因此,您的表单会在这些 onload 方法执行之前提交。 要解决此问题,您需要按照以下步骤操作

  1. 防止提交事件处理程序中出现默认值
  2. 将有效和无效图像的回调传递给 isImageValid 函数
  3. 如果图片有效,则手动提交表单

下面是代码。如果有帮助,请将答案标记为已接受

function isImageValid(idName, onValidCallback, onInvalidCallback) {
    var fileUpload = document.getElementById(idName);
    var fileName = document.getElementById(idName).value;

    if (typeof (fileUpload.files) != "undefined") {
        for (var i = 0; i < fileUpload.files.length; i++) {
            //    console.log(fileUpload.files[i]);
            //--------------------
            const allowedExtension = ['jpg', 'JPG', 'JPEG', 'jpeg', 'png', 'PNG'];
            const maxAllowedSize = 2048;
            const maxAllowedHeight = 200;
            const maxAllowedWidth = 200;

            const size = parseFloat(fileUpload.files[i].size / 1024).toFixed(2);
            const extension = fileName.split('.').pop();

            console.log({ size, extension });
            //Check for valid extension and size limit
            if (allowedExtension.some(ext => ext === extension) && size <= maxAllowedSize) {
                //Extension and size are valid
                // Now check for valid dimensions

                const reader = new FileReader();
                reader.readAsDataURL(fileUpload.files[i]);

                reader.onload = function (e) {
                    //Initiate the JavaScript Image object.
                    var image = new Image();

                    //Set the Base64 string return from FileReader as source.
                    image.src = e.target.result;

                    //Validate the File Height and Width.
                    image.onload = function () {
                        const height = this.height;
                        const width = this.width;

                        console.log({ height, width });
                        if (height > maxAllowedHeight || width > maxAllowedWidth) {
                            // alert("Height and Width must not exceed 200px.");

                            //File does not meet the dimensions guidline
                            if (onInvalidCallback)
                                onInvalidCallback();
                            return false;
                        }

                        //    alert("Uploaded image has valid Height and Width.");

                        //Everything is fine, form canbe submitted now
                        if (onValidCallback)
                            onValidCallback();
                    };
                };
            }
            break;
        }
    }
    else {
        // There are no files selected
        if (onInvalidCallback)
            onInvalidCallback();
    }
}

const form = document.getElementById('employee_form');
form.addEventListener('submit', (e) => {
    e.preventDefault();
    isImageValid('avatar', () => {
        alert('going to submit');
        document.getElementById("avatar").style.borderColor = "black";
        document.getElementById('avatar_validator_message').innerHTML = '';

        //Manually submit the form
        form.submit();
    },
        () => {
            alert('stop submit');
            document.getElementById("avatar").style.borderColor = "red";
            document.getElementById('avatar_validator_message').innerHTML = 'Invalid image';
        }
    );
    return false;    
});