You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bootstrap结合Ajax表单验证 beforeSend逻辑异常排查

问题核心原因

你的代码存在两个致命逻辑错误,导致请求被异常拦截无法正常发送:

  • 非空校验判断条件完全写反:当前逻辑是任意一个输入框不为空就终止请求,等同于只有所有输入框全空时才会发送请求,和非空校验的目标完全相反。正确的非空校验逻辑应该是:只要存在任意一个必填字段为空,就拦截请求,所有字段填写完成后才允许请求发送。
  • 文件字段校验方式错误:用value属性判断文件上传字段是否有值是无效的,多文件上传input需要通过files集合的长度判断是否选中了文件,原有判断逻辑就算用户选了文件也会判定为空。

另外你当前在校验失败时调用xhr.abort()会触发ajax的error回调,会弹出“发送失败”的错误提示,和校验失败的场景不匹配,更合理的方式是把校验逻辑前置到ajax调用之前执行,校验不通过直接返回,不发起ajax请求。

修正后可运行代码
$(document).ready(function () {
    var frm = $('#formulario');

    frm.submit(function (e) {
        e.preventDefault();

        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: new FormData(this),
            processData: false,
            contentType: false,
            beforeSend : function(xhr, opts) {
                // 修正判断逻辑:任意一个字段为空就拦截请求
                const nombreVal = document.getElementById('nombre').value.trim();
                const dniVal = document.getElementById('dni').value.trim();
                const correoVal = document.getElementById('correo').value.trim();
                const telefonoVal = document.getElementById('telefono').value.trim();
                const fechaVal = document.getElementById('fecha').value.trim();
                const lugarVal = document.getElementById('lugar').value.trim();
                const relacionVal = document.getElementById('relacion').value.trim();
                const detalleVal = document.getElementById('detalle').value.trim();
                const fileSelected = document.getElementById('archivo[]').files.length > 0;

                if (!nombreVal || !dniVal || !correoVal || !telefonoVal || !fechaVal || !lugarVal || !relacionVal || !detalleVal || !fileSelected)  {
                        frm.addClass('was-validated');
                        console.log("校验不通过,终止请求");
                        xhr.abort();
                }
            },
        
            success: function (data) {
                var div = document.createElement('div');
                div.appendChild(document.createTextNode("La denuncia fue enviada con éxito"));
                div.classList.add('alert', 'alert-success', 'mt-4', 'text-center');
                document.querySelector('form').appendChild(div);
                setTimeout(function() {
                    document.querySelector('.alert').remove();
                }, 5000);
                document.querySelector('form').reset();
                frm.removeClass('was-validated');
            },

            error: function (xhr, status) {
                // 区分是主动abort还是真的请求错误,避免校验失败弹发送失败提示
                if (status === 'abort') return;
                
                var div = document.createElement('div');
                div.appendChild(document.createTextNode("¡La denuncia no pudo ser enviada, por favor intente nuevamente!"));
                div.classList.add('alert', 'alert-danger', 'mt-4', 'text-center');
                document.querySelector('form').appendChild(div);
                setTimeout(function() {
                    document.querySelector('.alert').remove();
                }, 5000);
            },
        });
    });
});
优化建议

如果想让逻辑更清晰,避免abort带来的回调干扰,可以直接把校验逻辑移到发起ajax之前执行,不需要放在beforeSend钩子中:

frm.submit(function (e) {
    e.preventDefault();
    // 先做校验
    const nombreVal = document.getElementById('nombre').value.trim();
    const dniVal = document.getElementById('dni').value.trim();
    const correoVal = document.getElementById('correo').value.trim();
    const telefonoVal = document.getElementById('telefono').value.trim();
    const fechaVal = document.getElementById('fecha').value.trim();
    const lugarVal = document.getElementById('lugar').value.trim();
    const relacionVal = document.getElementById('relacion').value.trim();
    const detalleVal = document.getElementById('detalle').value.trim();
    const fileSelected = document.getElementById('archivo[]').files.length > 0;

    if (!nombreVal || !dniVal || !correoVal || !telefonoVal || !fechaVal || !lugarVal || !relacionVal || !detalleVal || !fileSelected)  {
        frm.addClass('was-validated');
        return false; // 校验不通过直接返回,不发起请求
    }

    // 校验通过再发ajax,不需要再写beforeSend校验逻辑
    $.ajax({
        type: frm.attr('method'),
        url: frm.attr('action'),
        data: new FormData(this),
        processData: false,
        contentType: false,
        success: function (data) {
            // 原有成功逻辑
        },
        error: function () {
            // 原有错误逻辑
        }
    })
})

内容的提问来源于stack exchange,提问作者Aaron Mas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 02:45:59