在本教程中,我们将使用 Ajax将Google reCAPTCHA v3添加到PHP表单中并提交而不离开页面。如果您的网站上有联系表格或任何此类表格,您就会知道从机器人接收垃圾邮件是多么令人讨厌。Google reCAPTCHA保护您免受垃圾邮件和其他自动滥用的侵害。要继续学习本教程,您需要具备HTML,jQuery和PHP的一些基本知识。
为什么选择Google reCAPTCHA v3?
我们所有人都有令人沮丧的经历,他们试图通过一种形式来快速提交一些信息,而这些形式最终只能面对验证码挑战。我们不得不输入随机字符,然后想知道“是两个V还是W?”,“是否应该添加该空格?”。
然后,我们必须选择所有具有斑马线或桥梁的图像,以证明我们是人类。值得庆幸的是,这些天来,许多网站都添加了Google reCAPTCHA v2,它仅显示一个复选框-“我不是机器人”。
但是,在2018年,Google发布了下一版本– reCAPTCHA v3,它根本不需要任何用户交互。它在后台工作,观察用户的行为。此版本为我们(开发人员)提供了一个分数,该分数指示了交互的可疑程度。我们可以使用该分数来防止垃圾邮件。在Google的官方网站管理员博客上了解其工作原理。
现在让我们学习如何将其添加到帝国CMS 的表单中。
第一步 注册reCAPTCHA v3密钥
您需要先注册您的网站并在此处获取密钥-https: //www.google.com/recaptcha/admin/create。添加标签,选择reCAPTCHA v3,输入您的域名并提交。
这将生成一个“站点密钥”和一个“秘密密钥”。复制两者并确保它们安全。我们将很快需要它们。
第二步 前端
让我们使用一个简单的联系表,其中包含全名,电子邮件和消息字段
HTML 页面
为了简化本教程,下面仅显示HTML代码。
加载 jQuery 库
使用网站密钥加载 JavaScript API
表单代码
<form action="/e/enews/index.php" id="contact-form" method="post" enctype="multipart/form-data" name="commonBottom" id="common">
<input type="hidden" name="enews" value="AddFeedback">
<input type="hidden" name="bid" value="2">
<input type="hidden" name="title" value="Common form">
<input type="hidden" name="ecmsfrom" value="9">
<input type="hidden" id="ref" value="RICHI" name="ref">
<input type="hidden" name="site" value="your site name">
<!-- 如果您查看reCAPTCHA v3文档,则需要grecaptcha.execute在希望保护的每个操作上调用。我们是表单提交。该调用会生成一个令牌,该令牌需要与我们的表单数据一起发送,以便在服务器端进行验证。最好的方法是在这样的表单中包含一个隐藏的输入字段,然后将令牌值动态分配给该字段: -->
<input type="hidden" name="recaptcha_response" id="recaptchaResponse">
<p class="label">Full Name *</p>
<input type="text" name="name" placeholder="Full Name" required>
<p class="label">Email *</p>
<input type="email" name="email" placeholder="Email" required>
<p class="label">Message *</p>
<textarea name="message" rows="6" placeholder="Type your message here" required></textarea>
<input type="submit" class="sub" value="Submit" id="formsubmit">
<!-- 下方隐藏的 div “alert”,用于在提交表单后显示从服务器收到的消息。如果同一个页面有多个表单,最好使用 class,因为 ID 为唯一值。 -->
<div class="alert"></div>
</form>
JS页面
Ajax表单提交
我们需要在表单提交时提出Ajax请求。
$('form').submit(function(event) {
event.preventDefault(); // 防止直接提交表单
$("form input.sub").val("Sending...").addClass("sending").attr("disable",true); // 显示“Sending...”让用户知道表单正在提交,并使用 disable 禁用 input 属性,防止多次点击。
$('.output').html("Sending... Don't refresh the page");
let dataForm = $(this).serialize(); // 序列化表单值,结果类型为 string。写在这里是为了当页面有多个表单,获取当前表单值。
// 调用以下函数,并用标记值填充隐藏的输入字段。发出Ajax请求时,这将自动包括令牌值以及其他表单数据。
grecaptcha.ready(function () {
// “action”值特定于此联系表单提交操作。在多个位置添加reCAPTCHA时,不同的操作可帮助分析整个网站上的数据。
grecaptcha.execute('YOUR_SITE_KEY_HERE', { action: 'contact' }).then(function (token) {
$("input[name='recaptcha_response']").val(token); // 将 token 值传递到当前页面所有表单中
// 在这里进行 Ajax 调用
$.ajax({
url: '/e/enews/index.php',
type: 'post',
data: dataForm + '&recaptcha_response=' + token, // 要加上新获取的 token 值
dataType: 'json',
success: function( _response ){
// Ajax 请求成功。 _response 是一个 JSON 对象
var error = _response.error;
var success = _response.success;
if(error != "") {
// 如果出现错误,将其显示给用户
$('.output').html(error);
$("form input.sub").val("Error").addClass("successed");
}
else {
// 如果成功,将其显示给用户
dataLayer.push({"event":"submitSuccess"}); // 传递事件 submitSuccess 到数据层,以便 GTM 可以获取转化成功的信息
$('.output').html(success);
$("form input.sub").val("Success").addClass("successed");
}
},
error: function(jqXhr, json, errorThrown){
// 在 Ajax 错误的情况下,显示结果以供演示
var error = jqXhr.responseText;
$('.output').html(error);
}
});
注意: reCAPTCHA令牌每两分钟过期一次。这就是为什么,仅在用户单击“提交”按钮之后以及在发出Ajax请求之前,才需要生成此令牌。
第三步:服务器端
在服务器端,我们需要验证收到的数据并发送 JSON 响应。
PHP 页面(/e/class/q_functions.php)
找到 AddFeedback 函数,并在内部添加验证语句。
reCAPTCHA 获取分数
在服务器端验证数据(名称,电子邮件和消息)后,我们需要从Google获取分数以验证它是否是人机交互。
$error_output = '';
$success_output = '';
// 构建 POST 请求以从 Google 获取 reCAPTCHA v3 分数
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = 'YOUR_SECRET_KEY_HERE'; // 在此处插入您的密钥
$recaptcha_response = $_POST['recaptcha_response']; // 发出 POST 请求获取 token
$recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response); // 把整个文件读入一个字符串中
重要说明:密钥仅用于服务器端。
解码并检查
收到的响应是 JSON 对象。
{
“ success”:true | false,//此请求是否为您网站的有效reCAPTCHA令牌
“ score”:数字//此请求的分数(0.0 – 1.0)
“ action”:字符串//此请求(非常重要):
“ challenge_ts”:时间戳,//质询加载的时间戳(ISO格式yyyy-MM-dd’T’HH:mm:ssZZ)
“ hostname”:字符串,//站点的主机名解决reCAPTCHA的
“错误代码”:[…] //可选
}
让我们来解码JSON对象$recaptcha和检查success,score和action。分数从0.0到1.0不等。默认情况下,您可以使用0.5的阈值。
$recaptcha = json_decode($recaptcha); // 对 JSON 格式的字符串进行解码,转换为 PHP 变量
// 根据返回的分数采取行动
if ($recaptcha->success == true && $recaptcha->score >= 0.5 && $recaptcha->action == 'contact') {
$success_output = "recaptcha ok";
} else {
$error_output = "Sorry, something went wrong, please refresh the page and try again.";
print_r("Sorry, something went wrong, please refresh the page and try again.");
// print_r($recaptcha); // 测试得分时使用
return;
}
替换 printerror
将帝国默认的 printerror 结果返回方式全部替换为 success_output 或者 error_output。
最后传参
$output = array(
'error' => $error_output,
'success' => $success_output
);
// 输出需要是JSON格式
echo json_encode($output);
完成!我们拥有使用 Ajax 进行表单提交的完整流程。
第四步:表单验证
你们都准备好了!点击该“submit”按钮,如果您正确集成了所有内容,则应该看到一条消息,说明已成功发送邮件。
需要验证以下方面:
- reCAPTCHA V3 分数拦截是否有效
- 成功与失败提示信息显示情况
- event 数据层传参情况是否成功,不会重复(通过 GTM 验证)
- 同页面不同表单是否都可以正常提交
第五步 隐藏 reCAPTCHA 图标(可选)
添加javascript API后,您可能已经注意到页面右下角的讨厌的reCAPTCHA徽章,看起来像这样。
这可能不适用于您的网站设计。如果您在用户流程中包含以下文字,则可以隐藏此徽章
This site is protected by reCAPTCHA and the Google
<a href="https://policies.google.com/privacy">Privacy Policy</a> and
<a href="https://policies.google.com/terms">Terms of Service</a> apply.
因此,将其添加p到“subm it”按钮下方的元素内。
现在,要真正隐藏徽章,只需将其添加到CSS中即可。
.grecaptcha-badge {
visibility: hidden;
}
恭喜你!已成功将Google reCAPTCHA v3设置为表单。现在,您将只收到来自人类的消息-无需他们面对验证码挑战,也无需离开页面。
参考来源:
https://developers.google.com/recaptcha/docs/v3?hl=zh-cn#actions
https://www.shejiku.net/recaptcha-v3tianjiaphpajaxtijiao.html