防止 HTML form 重複 submit

在 HTML form 的 Submit Event 觸發後,在 Http Request 的時間過久沒有馬上進行跳頁或是 Ajax 相關的 Callback 時,使用者可能會再次點擊按鈕造成有副作用的動作進行很多次,例如 Post 同樣的 Data 到後台,可能會有新增超過一筆資料,重複刪除…等等狀況發生,所以必須防止 HTML form 重複 submit。

做法有很多種:(用 jQuery 舉例)

做法一:在 Submit 期間 disable Submit 

$('#post-form').on('submit', function() {
    $(this).attr('disable', true);
    var url = '...',
        data = {...},
        afterPost = function() {
            $('#post-form').attr('disable', false);
        };
    $.post(url, data, afterPost);
});

優點:不能點
缺點:沒特別去調,樣式會變

做法二:在 Submit 過後 off event,Callback 再重 on event

var doPost = function() {
        $(this).off('submit', doPost);
        var url = '...',
            data = {...},
            afterPost = function() {
                $('#post-form').on('submit', doPost)
            };
        $.post(url, data, afterPost);
    }
}
$('#post-form').on('submit', doPost);

優點:動作最符合我們想要的意思
缺點:目前想不到有什麼缺點

做法三:在 Submit 過後在 form 上加上 class 或 data- 屬性,每次都判斷是否正在 Submit

// 也可以用 class 但比 data 更不明確
$('#post-form').on('submit', function() {
    if ($(this).data('submit') === 'true') {
        return false;
    } else { 
        $(this).data('submit', 'true');
        var url = '...',
            data = {...},
            afterPost = function() {
                $('#post-form').data('submit')
            };
        $.post(url, data, afterPost);
    }
});

優點:沒什麼優點,但用 class 可以順便設計樣式
缺點:語義比較不明確,混用不太好

做法四:在前台放一個 hidden input,提交後改變值,之後經由後端驗證

<input id="submit-flag" name="submit-flag" type="hidden" value="1">
<script>
    $('#post-form').on('submit', function() {
        $('#submit-flag').val('-1');
        var url = '...',
            data = {...},
            afterPost = function() {...};
        $.post(url, data, afterPost);
    });
</script>

接收 request 的PHP 部分

<?php
function handler() {
    if ($_POST['submit-flag'] === '-1') {
        return false;
    } else {
        ...
    }
}
?>

優點:沒什麼優點😄
缺點:前台能完成的事沒什麼道理交給後台做

做法五:如果只能 Submit 一次,可以用 jQuery 的 one method

// otherDoPost 為一個包括 post 的 function
$('#post-form').one('submit', otherDoPost); 

優點:很簡單
缺點:就真的只能用一次

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s