Alternative Architecture DOJO

オルターブースのクラウドネイティブ特化型ブログです。

【ASP.NET Core】Razor PagesでJavaScriptを使ってフォームの二重送信を防止する

みなさんこんにちは。 オルターブース、エンジニアの馬場です!
この記事はオルターブース Advent Calendar 2022の13日目のブログです。

adventar.org

アドベントカレンダーは25日までなので今日で折り返しです。あっというまですね…

入社してからはや2年、どちらかというとバックエンドをたくさん書いてきましたが、最近はフロントエンドを書く機会が多々ありました。

ということで今回はタイトル通り、ASP.NET Coreの「Razor Pages」でフォームの二重送信を防止するコードをJavaScriptで書く方法についてご紹介します。

フォームの二重送信を防ぐ仕組みはいろいろあると思いますが、今回は物理的にボタンを連打できないようにクライアントサイドで制御します。実装の流れは以下です。

  1. 送信ボタンを押す
  2. ボタンを非活性化する
  3. 送信する
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<form name="sampleForm">
    <input type="text" name="textBox">
    <button type="submit" id="submitButton" onclick="disabledSubmitButton('submitButton')">送信</button>
</form>

<script>
    function disabledSubmitButton() {
        let button = document.getElementById("submitButton");
        if (!button) {
            return;
        }

        // ボタンを二度押しできないようにする
        button.setAttribute("disabled", "");

        // フォーム送信
        let form = button.closest("form");    // 複数のformで利用できるように共通化する意味でこのようにformの特定をしています
        if (form) {
            form.submit();
            alert("送信されました");
        }
    }
</script>
</body>
</html>

ボタンを非活性にするためdisabled属性を付与し、submit()メソッド送信処理を実装しています。

単純にフォームの二重送信を防止するというだけであれば上記でやりたいことは実装できます。 しかしここで忘れたくないのがフォームのバリデーションの存在です。通常フォームを実行する前に入力で不備があればバリデーションを行うように実装しますよね。

learn.microsoft.com

ASP.NET Coreのバリデーションはクライアントサイド→サーバーサイドの順で行われます。つまりバリデーションを考慮する場合、サブミットボタンの連打対策を行うには以下の順序で実装する必要があります。

  1. サブミットが行われる
  2. クライアントサイドのバリデーション実行
  3. バリデーション問題なし→HTTP POSTリクエスト送信
  4. サーバーのバリデーション実行
  5. 送信!

1~3までをクライアントサイドで処理します。
ASP.NET Coreのクライアントサイドのバリデーションはjquery-validateのvalid()メソッドを使用することで呼び出し可能です。

learn.microsoft.com

function disabledSubmitButton() {
    let button = document.getElementById("submitButton");
    if (!button) {
        return;
    }

    let form = button.closest("form");
    let $jqform = $(form);

    // バリデーションを呼び出す
    if (form && $jqform.valid())
    ) {
        // ボタンを二度押しできないようにする
        button.setAttribute("disabled", "");

        // フォーム送信
        if (form) {
            form.submit();
        }
}

(HTMLは省略)

valid()メソッドを呼び出した後にdisabled属性を付与、submit()メソッドで送信処理を行うことで、無事にフォームの二重送信を防止できました。

参考:https://trungk18.com/experience/spinning-button-on-submit-jquery/

www.alterbooth.com

cloudpointer.tech

www.alterbooth.com