【问题标题】:JS Client Form Validation - Form still submits when formValidation function via eventListener for "submit" event returns false [duplicate]JS客户端表单验证-当表单验证功能通过addeventListener“提交”事件返回false时,表单仍然提交[重复]
【发布时间】:2020-09-16 10:12:12
【问题描述】:

我还是 JS 的初学者,所以这可能只是我没有很好的语言基础。

我正在尝试使用一个非常简单的 HTML 表单创建时间戳对象(想想 youtube 时间戳,但使用标题而不是时间),在发送发布请求之前进行验证。

为了提交表单,我故意不使用 JQuery 或内联事件处理程序,因为我想使用 eventListener。但是使用 eventListener,即使表单无效,表单仍然会被提交。

HTML 和 javascript 摘录,其中一些变量替换为下面的占位符:

# piece of timestamp_create_form.html
        <h3> New Timestamp </h3>
        <form class="timestamp-form" name="timestamp-form" action="URL_PLACEHOLDER" method="POST" enctype="multipart/form-data">
            <input type="hidden" name="csrfmiddlewaretoken" value="TOKEN_PLACEHOLDER">

            <div class="input-row">
                <div>
                    <input type="text" maxlength="100" id="id_name" placeholder="Timestamp-Title" class="input-title" name="name">
                    <label for="name"> Timestamp-Title </label>
                </div>
                <div>
                    <input type="text" id="id_time" maxlength="8" value="00:00:00" name="time" class="input-time">
                    <label for="time"> Time </label>
                </div>
            </div>
            <div class="form-buttons">
                <div><input type="submit" class="btn" value="Create Timestamp"></div>
                <div><a class="button" id="cancel-timestamp-creation" href="#"> Cancel </a></div>
            </div>
        </form>


# timestamp.js
// Add Event Listener to the form for the "onsubmit" event
document.forms['timestamp-form'].addEventListener('submit', function(){ return validateTimestampForm();} );
// I also tried this second variant, it did not work either
// document.forms['timestamp-form'].addEventListener('submit', validateTimestampForm);


function validateTimestampForm(){
    const timestampForm = document.forms['timestamp-form'];
    
    const timestamp_time_string = timestampForm['time'].value;
    const hours = parseInt(timestamp_time_string.substring(0,2));
    const minutes = parseInt(timestamp_time_string.substring(3,5));
    const seconds = parseInt(timestamp_time_string.substring(6,8));
    let timestamp_seconds = 3600*hours + 60*minutes + seconds;
    if (timestamp_seconds > 7200){
        alert("The time you entered is past the duration of the audio file!");
        return false;
    }
    
    const timestamp_name = timestampForm['name'].value;
    if (timestamp_name === ""){
        alert("Timestamp title must be filled out!");
        return false; 
    }
    
    return true;
}

我的错误在哪里?

我最初在 onsubmit="return validateForm()" 使用内联事件处理程序,但出于最佳实践原因以及能够通过 CSP 禁止内联 javascript,我想放弃它。

我发现其他问题的答案是指 JQuery 或使用内联事件处理程序,我希望避免这两种情况。最后一个建议将验证函数直接传递给 eventListener,而不是创建一个匿名函数,我尝试过(参见上面的 cmets)但没有成功。

【问题讨论】:

    标签: javascript html forms


    【解决方案1】:

    你就像内联拒绝拒绝:

    onsubmit="false"
    

    不同于:

    onsubmit="return false"
    

    我只会内联:

     <form onsubmit="return validateTimestampForm()"...
    

    或许你可以在按钮上定义一个 onclick() 事件,然后手动提交表单:

    <div><input id="sb" type="button" class="btn" value="Create Timestamp" ></div>
    <script>
        document.getElementById("sb").onclick = event=>{
            if (validateTimestampForm()) document.forms['timestamp-form'].submit();
        }
    </script>
    

    *** 编辑 ***

    所以这是我们想出的最终解决方案:

    document.forms['timestamp-form'].addEventListener('submit', function(event){ 
        if (!validateTimestampForm()) event.preventDefault(); 
    } );
    

    【讨论】:

    • 内联事件处理程序的问题是它们不能很好地配合内容安全策略 (CSP) 措施,这会阻止所有内联 JavaScript。并且考虑到不使用内联 javascript 无论如何都是最佳实践,对我来说使用 EventListener 似乎更明智。我不完全确定如何用 eventListener 正确表达“return false”。 addEventListener('submit', return function(){ return validateForm()}); 在语法上不正确,所以如果我必须在某处放一个 return 语句,我不完全确定如何。
    • CSP 阻止所有内联 javascript 是什么意思?应该有一种方法来声明 CSP,以便它允许内联 javascript。
    • 我同意您可以使用 nonce/hashes 来允许您运行内联 javascript 的特定情况,但鉴于此事件特别不应该那么困难和可避免,它似乎不太优雅走那么远。
    • 解决了!是的,这就是问题所在。对于未来的读者:这一切都是为了防止验证的提交操作的默认行为是错误的,需要手动抑制。我会将这个问题标记为另一个问题的重复,谢谢您的帮助!我一定错过了那个。
    猜你喜欢
    • 1970-01-01
    • 2011-06-22
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多