ダブルサブミット防止(submit();関数でonsubmitハンドラを呼ぶ)

通常のbuttonやanchorでも簡単にダブルサブミットを防止する方法。

onsubmit関数は

input type="submit"
input type="image"

をクリックした際にしか呼ばれません。
javascriptから、submit();関数を使用した場合は呼ばれません。

ダブルサブミット防止には、いくつか方法が考えられます。

1.ボタンやformをdisabledする方法(setTimeoutを使用等)
2.フラグを利用する方法
3.サーバ側でTransactionTokenチェック

2.の方法はかなり簡単に実装出来ますが、javascriptのsubmit()関数では
onsubmitイベントハンドラが呼ばれない為
通常のボタンやアンカーでは使用出来ません。


そこで、ダミーのsubmitボタンをクリックする方法で簡単に実現します。
画面に表示しないダミーのsubmitボタンを用意して
それをクリックする事でonsubmit()が呼ばれるように細工します。

<html>
<head>
<title>test</title>
<script>
var submitted = false;
function submitfunc(){
  if(submitted){
    alert('送信中');
    return false;
  }else{
    submitted = true;
    return true;
  }
}
function submitForm(){
  var f = document.forms[0];
  //f.submit(); // <= これだとonsubmit()が呼ばれない
  f.dummyBtn.click(); // <= submitをクリック
}
</script>
</head>
<body>
<form onsubmit="return submitfunc();" method="post" action="http://hoge.google.com">
<input type="submit" value="submit button"/><br/>
<input type="image" alt="submit image"/><br/>
<hr/>
<input type="button" value="normal button" onclick="submitForm();"/><br/>
<a href="#" onclick="submitForm();">test anchor</a>
<span style="display: none;">
 <input type="submit" value="dummy" id="dummyBtn" name="dummyBtn" />
</span>
</form>
</body>
</html>

この方法を使うと、画面上の全てのボタン、画像、アンカーのクリックにおいて
onsubmitハンドラが呼ばれるようになるので、2重送信が検出可能となります。


TeedaS2JSFにもダブルサブミット防止を考えていますが
サーバ側のTransactionTokenとクライアント側での抑止の両方が出来ればといいなぁw