cms icon indicating copy to clipboard operation
cms copied to clipboard

三个关于表单验证的bug

Open kuzzh opened this issue 7 months ago • 2 comments

  1. MinValue 验证错误

    在后台表单中对某个字段设置 MinValue 验证规则,参数设为 1。在前台填写表单时,该字段填写 0 也能验证通过。调了下代码,发现是 /sitefiles/assets/js/utils.js 这个文件中 utils.validateMinValue 实现有问题:

    validateMinValue: function (rule, value, callback) {
        if (!value) {
        callback();
        } else if (!/^-?\d+(\.\d{1,2})?$/.test(value)) {
        callback(new Error(rule.message || '字段必须是数值,并且不能小于指定的值'));
        } else if (value && parseInt(value) < parseInt(rule.value)) {
        callback(new Error(rule.message || '字段必须是数值,并且不能小于指定的值'));
        } else {
        callback()
        }
    }
    

    从上面代码可以看出,当 value = 0 时,直接就执行 callback() 了,不会执行验证逻辑。修复参考实现:

    if (value !== undefined && value !== null && value !== '') {
        if (/^-?\d+(\.\d{1,2})?$/.test(value)) {
            const v = parseFloat(value);
            const minValue = parseFloat(rule.value);
            if (v >= minValue) {
                callback();
                return;
            }
        }
    }
    callback(new Error(rule.message || "字段必须是数值,并且不能小于指定的值"));
    

    其它验证方法可能也存在类似的问题,希望能一并修复。

  2. Regex 未得到预期验证结果

    在后台表单中对某个字段设置 Regex 验证规则,正则表达式为:^[1-9][0-9]*$,作用是限制字段的值是不能小于 1 的整数。在前台填写表单时,发现验证没有得到预期结果,输入1,2,3,4...都会返回 false。调了下代码,发现问题出在 /sitefiles/assets/js/utils.js 这个文件 getRules 方法里。在这个方法里,当验证规则类型为 regex 的时候创建了一个正则表达式对象,并构造了个对象添加到了 array 中:

    else if (ruleType === 'regex' && rule.value) {
        var re = new RegExp(rule.value, 'ig');
        array.push({
        type: "string",
        pattern: re,
        message: rule.message || options.regex,
        });
    }
    

    问题就出在构造的这个对象里不该设置 type: "string",将其注释掉就好了。其它地方的正则表达式验证规则也有这个问题,希望一并修复。

  3. utils.getRules 方法中 options 对象构造问题

    在调试第二个问题的时候,发现 getRules 方法中从 options 对象中获取错误提示信息获取不到,options 是个数组,后面却用 options.requiredoptions.email 等直接获取,所以没获取到。建议修改 options 的结构如下:

    var options = {
      required: '字段为必填项',
      email: '字段必须是有效的电子邮件',
      mobile: '字段必须是有效的手机号码',
      url: '字段必须是有效的url',
      alpha: '字段只能包含英文字母',
      alphaDash: '字段只能包含英文字母、数字、破折号或下划线',
      alphaNum: '字段只能包含英文字母或数字',
      alphaSpaces: '字段只能包含英文字母或空格',
      decimal: '字段必须是数字',
      digits: '字段必须是整数',
      max: '字段不能超过指定的长度',
      maxValue: '字段必须是数值,并且不能大于指定的值',
      min: '字段不能低于指定的长度',
      minValue: '字段必须是数值,并且不能小于指定的值',
      regex: '字段必须匹配指定的正则表达式',
      chinese: '字段必须是中文',
      zip: '字段必须是邮政编码',
      idCard: '字段必须是身份证号码',
    };
    

kuzzh avatar Jul 14 '24 07:07 kuzzh