簡體   English   中英

如何使用 Google ReCaptcha V2 Invisible AND Multiple Forms 執行 HTML 表單驗證?

[英]How do I perform HTML form validation with Google ReCaptcha V2 Invisible AND Multiple Forms?

我在頁面上有 2 個表單,它們都需要 Google ReCaptcha V2 Invisible。 我使用以下代碼完美地工作。

在標題中:

<script src='https://www.google.com/recaptcha/api.js?onload=myCallBack&render=explicit' async defer></script>

這是表格。 很簡單。 您可以看到 ReCaptcha 與按鈕相關聯,並且它具有唯一的回調和 ID。

<form id="subForm" action="form-processing.php" method="POST">         
    <input placeholder="Name" id="name" name="fname" type="text" required/>
    <input placeholder="Email" id="email" name="email" type="text" required/>
    <textarea placeholder="Comments" id="comments" cols="30" name="comments" rows="6" required></textarea>

    <button class="g-recaptcha form-submit-button" data-sitekey="MySiteKey" data-callback="captchaSubmit2" id="recaptcha2">Submit</button>
</form>

當標題中的 ReCaptcha api 加載並觸發 onload 回調 (myCallBack) 時,將調用以下代碼以在表單的每個按鈕上呈現 ReCaptcha。

var recaptcha1;
var recaptcha2;
var myCallBack = function() {
    //Render recaptcha1 on element with ID "recaptcha1"
    recaptcha1 = grecaptcha.render('recaptcha1', {
      'sitekey' : 'MySiteKey',
      'theme' : 'light'
    });

    //Render recaptcha2 on element with ID "recaptcha2"
    recaptcha2 = grecaptcha.render('recaptcha2', {
      'sitekey' : 'MySiteKey',
      'theme' : 'light'
    });
};

最后,當點擊提交按鈕時,ReCaptcha 處理並使用按鈕上指定的回調來觸發實際的表單提交。

function captchaSubmit1(data) {
    document.getElementById("mainForm").submit();
}
function captchaSubmit2(data) {
    document.getElementById("subForm").submit();
}

在服務器端處理的后端,我使用以下代碼來驗證 ReCaptcha。

<?php
    // reCaptcha info
    $secret = "MySecretKey";
    $remoteip = $_SERVER["REMOTE_ADDR"];
    $url = "https://www.google.com/recaptcha/api/siteverify";

    // Form info
    $first = $_POST["first"];
    $last = $_POST["last"];
    $response = $_POST["g-recaptcha-response"];

    // Curl Request
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, array(
        'secret' => $secret,
        'response' => $response,
        'remoteip' => $remoteip
        ));
    $curlData = curl_exec($curl);
    curl_close($curl);

    // Parse data
    $recaptcha = json_decode($curlData, true);
    if ($recaptcha["success"])
    { 
       /// MY DATA VALIDATION & EMAILING OF FORM DATA ///
    }else{
        header('Location: /thank-you-for-contacting-us/?gvx');
        exit;
    }
?>

如果表單驗證由於 Google ReCaptcha 驗證失敗而失敗,它只是重定向到帶有代碼的感謝頁面,所以我知道這是失敗的 recaptcha。 如果表單字段數據未通過驗證,則有一個單獨的代碼。 只是一種幫助我了解正在發生的事情的方法。

好的! 所以現在的問題是這些表單不執行 HTML 客戶端字段驗證。 我試圖合並這個解決方案但沒有運氣: How to run reCaptcha ONLY if HTML5驗證通過?

這些代碼是那篇文章的主要內容。 我更換了提交按鈕:

前:

<button class="g-recaptcha form-submit-button" data-sitekey="MySiteKey" data-callback="captchaSubmit2" id="recaptcha2">Submit</button>

后:

<button class="form-submit-button" type="submit">Submit</button>

我將這個 div 添加到提交按鈕上方的表單中:

<div id="recaptcha2" class="g-recaptcha" 
data-sitekey="MySiteKey"
data-size="invisible"
data-callback="captchaSubmit2">

這些是表單提交的新處理程序:

$('#mainForm').submit(function (event) {
    if (!grecaptcha.getResponse()) {
        event.preventDefault(); //prevent form submit
        grecaptcha.reset();
        grecaptcha.execute();
    } 
});
$('#subForm').submit(function (event) {
    if (!grecaptcha.getResponse()) {
        event.preventDefault(); //prevent form submit
        grecaptcha.reset();
        grecaptcha.execute();
    } 
});

所以這里的最終流程是頁面加載 api,api 調用在 g-recaptcha div 上呈現 recaptcha 的 recaptcha 呈現器,提交表單,阻止默認行為,允許 HTML 驗證起作用(它這樣做) ,當表單真正提交時,它會觸發上述函數調用 grecaptcha.execute(); 哪個進程,當它完成時,調用綁定到它的回調函數 (captchaSubmit2),它執行真正的最終提交。 然后我的服務器端腳本沒有通過谷歌驗證,悲傷隨之而來......

我現在已經花了兩天時間來解決這個問題,通常的“完成了嗎?” 從上面回響。 我離我很近,我可以嘗到它的味道,但我顯然錯過了一些東西。

我只需要 Google ReCaptcha V2 Invisible 在同一頁面上處理 2 個表單,並對必填字段進行 HTML 表單驗證。

任何幫助將不勝感激。

經過大量搜索,我終於找到了一個有效且相當優雅的解決方案,因為它支持單個頁面上的多種表單,並且是動態的。 它搜索頁面並將 recaptcha 附加到任何匹配的標記 div。 它應該在一頁上支持盡可能多的表單。

這是它附加的標簽:

<div class="recaptcha-holder"></div>

我仍然不確定為什么我自己的實現不起作用。 每次我將 recaptcha 附加到多個表單時,服務器端處理都會失敗,並且調試顯示它沒有收到 recaptcha 數據。

請注意,這是在 WordPress 網站上實現的,所以我將 javascript 添加到我現有的 js 包含中,我將自定義代碼放入其中。

此代碼是Mch ( https://stackoverflow.com/users/7327512/mch ) 發布的有關此問題的最后一個條目( 從 Google 實現新的 Invisible reCaptcha )。 感謝他們提供的前端解決方案。 有趣的是,它是在 2016 年底發布的。

Mch 的前端示例

<!DOCTYPE html>
<html>
<body>

<form action="" method="post">
    <input type="text" name="first-name-1"> <br />
    <input type="text" name="last-name-1"> <br />

    <div class="recaptcha-holder"></div>

    <input type="submit" value="Submit">
</form>

<br /><br />

<form action="" method="post">
    <input type="text" name="first-name-2"> <br />
    <input type="text" name="last-name-2"> <br />

    <div class="recaptcha-holder"></div>

    <input type="submit" value="Submit">
</form>
<script src="https://www.google.com/recaptcha/api.js?onload=renderGoogleInvisibleRecaptcha&render=explicit" async defer></script>
</body>
</html>

Mch 的 Javascript(添加到我現有的 JS 包括)

  var renderGoogleInvisibleRecaptcha = function() {
    for (var i = 0; i < document.forms.length; ++i) {
      var form = document.forms[i];
      var holder = form.querySelector('.recaptcha-holder');
      if (null === holder){
        continue;
      }

      (function(frm){

        var holderId = grecaptcha.render(holder,{
          'sitekey': 'CHANGE_ME_WITH_YOUR_SITE_KEY',
          'size': 'invisible',
          'badge' : 'bottomright', // possible values: bottomright, bottomleft, inline
          'callback' : function (recaptchaToken) {
            HTMLFormElement.prototype.submit.call(frm);
          }
        });

        frm.onsubmit = function (evt){
          evt.preventDefault();
          grecaptcha.execute(holderId);
        };

      })(form);
    }
  };

最后我的后端(服務器端)處理:

<?php
    // reCaptcha info
    $secret = "MySecretKey";
    $remoteip = $_SERVER["REMOTE_ADDR"];
    $url = "https://www.google.com/recaptcha/api/siteverify";

    // Form info
    $first = $_POST["first"];
    $last = $_POST["last"];
    $response = $_POST["g-recaptcha-response"];

    // Curl Request
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, array(
        'secret' => $secret,
        'response' => $response,
        'remoteip' => $remoteip
        ));
    $curlData = curl_exec($curl);
    curl_close($curl);

    // Parse data
    $recaptcha = json_decode($curlData, true);
    if ($recaptcha["success"])
    { 
        // MY DATA VALIDATION & EMAILING OF FORM DATA
    }else{
        // Google ReCaptcha Failed to Verify - Send to False Positive
        header('Location: /thank-you-for-contacting-us/?gvx');
        exit;
    }
?>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM