PHPフォームはいくつかのタブで構成されており、reCaptchaでタイムアウトします。すべてが1つのページで実行され、フォームが3分未満で完了した場合は問題なく機能します。
ソリューションのアイデアは、フォーム処理とreCaptchaを処理のために2次ページに移動することです。
問題は、フォームページがreCaptchaのgoogleサービスをポーリングし、非表示フィールドにトークン値を収集することです。
<input type="hidden" name="recaptcha_response" id="recaptchaResponse">
問題は、サーバー側の処理ページでこのトークンをリクエストする方法ですか?これは、クライアント側のフォームページで使用されるコードです。トークン値を再生成して、次のように適用する必要があります。
$ recaptcha_response
これがフォームページの作業バージョンです。フォームページからのトークンの投稿に関する要件を削除するのは簡単ですが、サーバー側のページで使用するトークンを再生成する方法がわからないだけです。
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['recaptcha_response'])) {
// Build POST request:
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = RECAPTCHA_SECRET_KEY;
$recaptcha_response = $_POST['recaptcha_response'];
$remoteip = $_SERVER['REMOTE_ADDR'];
// Make and decode POST request:
$recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response. '&remoteip='.$remoteip);
$recaptcha = json_decode($recaptcha);
// Take action based on the score returned:
if ($recaptcha->score >= 0.5) {
追加する編集:これはオプションのようなので、送信までreCaptchaの初期化を行ってタイミングの問題を遅らせます:
https://developers.google.com/recaptcha/docs/v
「2.アクションまたはページのロード時にgrecaptcha.executeを呼び出す」
コードをあまり変更したくない場合は、別の方法として、名前付き関数にreCaptcha JavaScriptをラップし、間隔を設定してその関数をポーリングし、reCaptchaに3分ごとに新しいトークンをフォーム要素に追加するように要求します。
function getReCaptcha(){
grecaptcha.ready(function() {
...
});
}
getReCaptcha(); // This is the initial call
setInterval(function(){getReCaptcha();}, 150000);
<script type="text/javascript">
function grecaptcha_execute(){
grecaptcha.execute('RECAPTCHA_SITE_KEY', {action: 'homepage'}).then(function(token) {
document.getElementById('recaptchaResponse').value=token;
});
}
grecaptcha.ready(function() {
grecaptcha_execute();
});
</script>
<?php
if ($recaptcha->success) {
echo '<p style="color: #0a860a;">CAPTCHA was completed successfully!</p>';
}else{
$error_codes = 'error-codes';
if (isset($Retorno->$error_codes) && in_array("timeout-or-duplicate", $Retorno->$error_codes)) {
$captcha_msg = "The verification expired due to timeout, please try again.";
?>
<script>grecaptcha_execute();</script>
<?php
} else {
$captcha_msg = "Check to make sure your keys match the registered domain and are in the correct locations.<br> You may also want to doublecheck your code for typos or syntax errors.";
}
echo '<p style="color: #f80808;">reCAPTCHA error: ' . $captcha_msg . '</p>';
}
?>
フォームを送信するときに、recaptchaを実行するだけです。
<script>
function grecaptcha_execute(){
grecaptcha.execute('RECAPTCHA_SITE_KEY', {action: 'homepage'}).then(function(token) {
document.getElementById('recaptchaResponse').value=token;
});
}
</script>
<form onsubmit="grecaptcha_execute()" action="script.php">
...
</form>