質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.23%

お問い合わせフォームでgoogle reCTPTCHAv2 の実装時のエラー

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 135

cyamio

score 4

前提・実現したいこと

お問い合わせフォームでgoogle reCTPTCHAv2を実装した際、チェックを入れなければ送信されないようにしたい

発生している問題・エラーメッセージ

バリデーションは問題なく進んだがチェックを入れずに「送信ボタン」を押すと、「チェックを入れてください」と表示されたあと送信されてしまいます。

エラーメッセージ
イメージ説明

該当のソースコード

ソースコード
index.php 冒頭部分

<?php
// セッションを開始
session_start();

// セッションIDを変更(セッションハイジャック対策)
session_regenerate_id(TRUE);

//reCAPTCHA の情報(Site Key)の読み込み
require_once('./recaptchavars.php');

// //データの検証とエスケープ処理の関数の読み込み
require './functions.php';

//初回以外ですでにセッション変数に値が代入されていれば、その値を。そうでなければNULLで初期化
$name = isset($_SESSION['name']) ? $_SESSION['name'] : NULL;
$email = isset($_SESSION['email']) ? $_SESSION['email'] : NULL;
$message = isset($_SESSION['mmessage']) ? $_SESSION['message'] : NULL;
$error = isset($_SESSION['error']) ? $_SESSION['error'] : NULL;

//CSRF対策の固定トークンを生成
if(!isset($_SESSION['ticket'])){
  //セッション変数にトークンを代入
  $_SESSION['ticket'] = sha1(uniqid(mt_rand(), TRUE));
}

//トークンを変数に代入
$ticket = $_SESSION['ticket'];

 ?>

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0">

    <title>SAYAKA ONO -portfolio-</title>

    <link href="https://fonts.googleapis.com/css?family=Spinnaker&display=swap" rel="stylesheet">
    <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
    <link rel="stylesheet" href="css/normalize.css">
    <link rel="stylesheet" href="css/style.css">

    <!-- <script src="https://www.google.com/recaptcha/api.js" async defer></script> -->
    <script src="js/jquery-3.4.1.min.js"></script>

    <!-- reCAPTCHA -->
    <script type="text/javascript">
      var onloadCallback = function() {
        grecaptcha.render('recaptcha', {
          'sitekey' : "<?php echo RC_SITE_KEY; ?>",
          'callback' : verifyRecaptcha,
          'expired-callback' : expiredCallback,
          'theme' : 'light',
          'size' : 'compact'
        });
      };
      var verifyRecaptcha = function(response) {
        if(response != "") {
            document.getElementById('recaptcha').className = "g-recaptcha verified";
            var recaptchaError = document.getElementById('recaptcha_error');
            if(recaptchaError != null) {
               recaptchaError.parentNode.removeChild(recaptchaError);
            }
            var recaptchaExpired  = document.getElementById('expired');
            if(recaptchaExpired != null) {
               recaptchaExpired.parentNode.removeChild(recaptchaExpired);
            }
        }
      };
      var  expiredCallback = function() {
        var p = document.createElement('p');
        p.textContent = 'チェックボックスをもう一度オンにしてください。';
        p.setAttribute('class', 'error');
        p.setAttribute('id', 'expired');
        var recaptcha_div = document.getElementById('recaptcha');
        var recaptchaExpired  = document.getElementById('expired');
        if(recaptchaExpired == null) {
          recaptcha_div .appendChild(p);
        }
        document.getElementById('recaptcha').className = "g-recaptcha";
      };
    </script>
    <!-- reCAPTCHA -->


script.php 

```  $("form").submit(function(){ //submit イベント  
//エラー表示の初期化  
$("p.error").remove();  

//reCAPTCHA の検証  
if(!$('#recaptcha').hasClass('verified')) {  
$('#recaptcha').append("<p class='error' id='recaptcha_error'>チェックを入れてください</p>");  

}  

//error クラスの追加の処理  
if($("p.error").length() > 0){ //エラーがあれば  

$("p.error").parent().addClass("error"); //親要素にクラスを追加  
}  
//エラーがあれば送信しない  
if($("p.error").length() > 0){  
return btn_flg = false;  

}  
});  


contact.js  部分  
let form_confirm = document.getElementById('form-confirm');  


// 送信後の装飾  
let submit_btn = document.getElementById('send-btn');  
let recaptcha = document.getElementById('recaptcha');  
let return_message = document.getElementById('return-message');  

form_confirm.addEventListener('click', () => {  
// フォームの名前  
let form_name = document.getElementById('form-name').value; //  
let confirm_name = document.getElementById('confirm-name');  
let name = document.getElementById('name');  


// フォームのメールアドレス  
let form_email = document.getElementById('form-email').value;//  
let confirm_email = document.getElementById('confirm-email');  
let email = document.getElementById('email');  

// フォームの問い合わせ内容  
let form_content = document.getElementById('form-content').value;  
let confirm_content = document.getElementById('confirm-content');  
let message = document.getElementById('message');  

// ボタンの表示有無  
let send_btn = document.getElementById('mail-form');  

// 初期化  
confirm_name.classList.remove('text-danger');  
confirm_email.classList.remove('text-danger');  
confirm_content.classList.remove('text-danger');  

let btn_flg = true;  

// フォームのバリデーション  
// 未入力検出  
if (form_name === '') {  
form_name = '名前が未入力です。'  
confirm_name.classList.add('text-danger');  
btn_flg = false;  
}  

// フォームのバリデーション  
// 未入力検出  
if (form_email === '') {  
form_email = 'メールアドレスが未入力です。'  
confirm_email.classList.add('text-danger');  
btn_flg = false;  
} else {  
// メールフォーマットのバリデーション  
if (form_email.match(/.+@.+\..+/) === null) {  
form_email = '不正なメールアドレスです。正しい形式例:sample@sayaka-log.com'  
confirm_email.classList.add('text-danger');  
btn_flg = false;  
}  
}  

// フォームのバリデーション  
// 未入力検出  
if (form_content === '') {  
form_content = 'お問い合わせ内容が未入力です。'  
confirm_content.classList.add('text-danger');  
btn_flg = false;  
}  

// 送信ボタンの表示有無  
if (btn_flg === false) {  
send_btn.style.display = 'none';  
} else {  
send_btn.style.display = 'block';  
close.style.display = 'none';  
}  

confirm_name.textContent = form_name;  
name.value = form_name;  
confirm_email.textContent = form_email;  
email.value = form_email;  
confirm_content.textContent = form_content;  
message.value = form_content;  
});  

(() => {  

let server = './sendmail.php'; //送信先サーバーのURLを設定する;  

let xhr = new XMLHttpRequest();  
let form = document.getElementById('mail-form');  
let formHTML = form.innerHTML;  
let tempForm = {};  

form.onsubmit = (e) => {  
e.preventDefault();  
//多重送信を防止;  
let submit = form.querySelector('input[type="submit"]');  
submit.disabled = false;  

//formの内容を保存;  
(() => {  
let elements = form.elements;  
for(var i = 0; i < elements.length; i++) {  
tempForm[elements[i].name] = elements[i].value;  
}  
})();  

//サーバーにFormDataを送信;  
(() => {  
//FormDataを取得し、送信元サーバーを追加;  
let formData = new FormData(form);  
formData.append('from', location.host);  

xhr.open('POST', server);  
//カスタムヘッダーをつける;  
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');  
//結果はjsonだが、IEが対応していないのでtextで受け取る;  
xhr.responseType = 'text';  
xhr.timeout = '10000';  
xhr.send(formData);  
})();  
};  

xhr.addEventListener('loadend', () => {  
//ボタンを削除  
submit_btn.classList.add('hidden');  
recaptcha.classList.add('hidden');  

// let spinner = document.getElementById('spinner');  
// spinner.classList.remove('hidden');  

if(xhr.status === 200) {  
let response = JSON.parse(xhr.response);  
if(response.result) {  
//メールが送信された時の処理;  
// resultElements.p.textContent = '送信に成功しました。';  
// spinner.classList.add('hidden');  
return_message.childNodes[0].textContent = 'メールの送信が完了しました。';  
return_message.childNodes[1].textContent = '担当から連絡しますので少々お待ちください。';  
return_message.classList.remove('hidden');  
return;  
}  
}  
//メールが送信されなかった時の処理;  
// spinner.classList.add('hidden');  
return_message.childNodes[0].textContent = '送信に失敗しました。';  
return_message.childNodes[1].textContent = 'ページを更新して再度送信していただくか、しばらく経ってから連絡ください。';  
return_message.classList.remove('hidden');  
return;  
}, false);  
})();  

試したこと

.length を .size にしましたが同じエラーでした。こちらです。

[
[追記」
エラー文章は
Type Error: $(...).length is not a function です。

lengthの後ろに()がついていたのでそれをとって見たところ、チェックをしていないのに「チェックを入れてください」も表示されず送信されてしまいます。

よろしくおねがします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2019/12/25 21:26

    エラーが起こっているコードと提示されているコードが違います。また、エラー文は画像だけでなくテキストでも提示してください。

    キャンセル

  • cyamio

    2019/12/25 21:32

    失礼いたしました。
    $("form").submit(function(){ //submit イベント
    //エラー表示の初期化
    $("p.error").remove();

    //reCAPTCHA の検証
    if(!$('#recaptcha').hasClass('verified')) {
    $('#recaptcha').append("<p class='error' id='recaptcha_error'>チェックを入れてください</p>");

    }

    //error クラスの追加の処理
    if($("p.error").length() > 0){ //エラーがあれば

    $("p.error").parent().addClass("error"); //親要素にクラスを追加
    }
    //エラーがあれば送信しない
    if($("p.error").length() > 0){
    return btn_flg = false;

    }
    });

    こちらです。

    エラー文章は
    Type Error: $(...).length is not a function です。

    lengthの後ろに()がついていたのでそれをとって見たところ、チェックをしていないのに「チェックを入れてください」も表示されず送信されてしまいます。

    キャンセル

  • kei344

    2019/12/25 21:40

    (質問文は編集できます)この「質問への追記・修正の依頼」の部分はデフォルトで表示されませんので、質問本文に追記することをお勧めします。

    キャンセル

  • cyamio

    2019/12/25 21:45

    ご指摘ありがとうございます。修正しました。

    キャンセル

回答 1

0

lengthの後ろに()がついていたのでそれをとって見たところ

エラーはそれをすれば出なくなります。
return btn_flg = false; こう書いても別スコープなので変数に代入されることはありません。

送信されてしまいます。 

とりあえず return false; にすれば多分 送信されないと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる