同じForm内に複数のreCAPTCHA認証ボタンを設置する
投稿日:
WEBページのreCAPTCHA対応しているform内に複数のsubmitボタンを設置する方法です。
前提としてPOSTデータより g-recaptcha-response
を取り出して認証しているとします。
単純にsubmitボタンを複数設置した場合、うまく動きません。
例えば、以下のようなフォームを作った場合
<script>
function mySubmit(){
document.getElementById("myForm").submit();
}
</script>
<form id="myForm" action="/hoge">
<button class="g-recaptcha" data-sitekey="各自のサイトキー" data-callback="mySubmit">送信1</button>
〜いろいろ〜
<button class="g-recaptcha" data-sitekey="各自のサイトキー" data-callback="mySubmit">送信2</button>
</form>
送信1ボタンのすぐ上に、このようなreCAPTCHA用の要素が生成されます。
<div>
<div class="grecaptcha-badge" 〜略〜 >
<div class="grecaptcha-logo">
<iframe src="https://www.google.com/recaptcha/〜略〜 ></iframe>
</div>
<div class="grecaptcha-error"></div>
<textarea id="g-recaptcha-response" name="g-recaptcha-response" 〜略〜 ></textarea>
</div>
</div>
そして、送信2ボタンのすぐ上にも同様に要素が生成されます。
送信1ボタンとの違いはiframe内とtextareaのidです。
textareaのidはボタンの数が増える毎に連番が付与されるようです。
<div>
<div class="grecaptcha-badge" 〜略〜 >
<div class="grecaptcha-logo">
<iframe src="https://www.google.com/recaptcha/〜略〜 ></iframe>
</div>
<div class="grecaptcha-error"></div>
<textarea id="g-recaptcha-response-1" name="g-recaptcha-response" 〜略〜 ></textarea>
</div>
</div>
このままではPOSTデータに同名のパラメータが存在してしまうので正常に動きません。
そこで、クリックしなかったボタンに紐づくreCAPTCHA要素は削除してしまいます。
具体的には以下のようなコードになります。
<script>
function mySubmit(delId){
document.getElementById(delId).parentNode.remove()
document.getElementById("myForm").submit();
}
function mySubmit1() {
mySubmit("g-recaptcha-response-1")
}
function mySubmit2() {
mySubmit("g-recaptcha-response")
}
</script>
<form id="myForm" action="/hoge">
<button class="g-recaptcha" data-sitekey="各自のサイトキー" data-callback="mySubmit1">送信1</button>
〜いろいろ〜
<button class="g-recaptcha" data-sitekey="各自のサイトキー" data-callback="mySubmit2">送信2</button>
</form>
これでPOSTデータにreCAPTCHAのパラメータが重複することはなくなるので
正常に認証することができるようになります。