同じForm内に複数のreCAPTCHA認証ボタンを設置する

投稿日:2018-10-26

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のパラメータが重複することはなくなるので
正常に認証することができるようになります。

関連する記事