reCAPTCHAはこう設置する

フォームにreCAPTCHAを設置するたびに検索してしまうので要点をまとめる。

reCAPTCHAのプロジェクトを作成してサイトキーとシークレットキーをGoogleから発行してもらう

https://cloud.google.com/security/products/recaptcha?hl=ja

サイトキーをフォームがあるHTMLのheadタグ内に

<script src="https://www.google.com/recaptcha/api.js?render=***サイトキー***"></script>

フォーム内に以下のrecaptchaResponseというinput

<form id="inquiry" action="" method="POST">
   <input type="hidden" name="recaptchaResponse" id="recaptchaResponse">
      //省略
   <button type="submit" id="sendBtn" name="sendBtn">送信</button>
      //省略
</form>

サーバサイドのプログラムにPOSTするには、そのままsubmitする方法もあるが、以下のようにJavascriptで送る必要がある場合の記述例を2つ。

1.画面遷移しないでサーバーサイドにフォームの内容を送信し結果のレスポンスを待つ場合

// Contact form
var form = $('#main-contact-form');
form.submit(function(event){
//htmlでの送信をキャンセル
  event.preventDefault();
  grecaptcha.ready(function() {
    //tokenを取得したらこれをrecaptchaResponseに格納しformをPOST
    grecaptcha.execute('***サイトキー***', {action: 'submit'}).then(function(token) {
     // Add your logic to submit to your backend server here.
     document.getElementById("recaptchaResponse").value = token;
     var form_status = $('<div class="form_status"></div>');
     $.ajax({
       url: form.attr('action'),
       type:form.attr('method'),
       data:form.serialize(),
       beforeSend: function(){
         form.prepend( form_status.html('<p><i class="fa fa-spinner fa-spin"></i> 送信中...</p>').fadeIn() );
         }
       }).done(function(data2){
          form_status.html('<p class="text-success">'+data2+'</p>').delay(3000).fadeOut();
       });
    });
  });
});

2.サーバーサイドに画面遷移する場合のjavascript

const sendBtn = document.getElementById('sendBtn');
document.getElementById("main-contact-form").addEventListener("submit", function(e) {
  //START validation(必須項目)
  const form = e.target;
  let isValid = true;
  let messages = [];
  //必須ラベルに対応するinput/textarea をチェック
  const requiredLabels = form.querySelectorAll("label.required");
  requiredLabels.forEach(label => {
    const name = label.getAttribute("for");
    const field = form.querySelector(`[name="${name}"]`);
    if (field && field.value.trim() === ""){
      isValid = false;
      messages.push(`「${label.textContent}」は必須項目です。`);
      field.classList.add("error");
      // 任意:エラー用スタイル
    } else {
      field.classList.remove("error");
    }
  });
  //END validation(必須項目)
  if (!isValid) {
    // 送信を止める
    e.preventDefault(); 
    alert(messages.join("\n"));
  }else{
    //START reCAPTCHA用スクリプト
    e.preventDefault();
    //送信を止める
    grecaptcha.ready(function () {
      grecaptcha.execute("***サイトキー***", {action: "submit"}).then(function(token) {
        //reCAPTCHAで発行されたトークンが変数tokenに格納されてい
        document.getElementById("recaptchaResponse").value = token;
        document.getElementById('main-contact-form').submit();
        //tokenをinputタグのvalueに入れた後に送信
      });
    });
  }

サーバ側のスクリプト

<?php
if (isset($_POST["recaptchaResponse"]) && !empty($_POST["recaptchaResponse"])) {
  $secret_key = "6LcaSH0qAAAAAJskyZzIMs2sBKjAAqLIoxK9wZ0x";
  $strURL="https://www.google.com/recaptcha/api/siteverify?   secret=".$secret_key."&response=".$_POST["recaptchaResponse"];
  $verifyResponse = file_get_contents($strURL);
  $reCAPTCHA = json_decode($verifyResponse);
  if ($reCAPTCHA->success == false){
    echo "送信できませんでした";
  }else{
    //reCAPTCHAが通った時の処理
    //フォームの内容でメール飛ばすとか
  }
}else{
  echo 'TOKENがありません';
}

More Reading

Post navigation

Leave a Comment

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です