jQuery ajax 的隐形 ReCaptcha
Invisible ReCaptcha with jQuery ajax
我正在尝试使用 jQuery 和 "ajax" 请求在表单中实施最新的 ReCaptcha(又名 "invisible" ReCaptcha)。
ReCaptcha 文档:https://developers.google.com/recaptcha/docs/invisible
我的表格:
<form id="myForm" >
<input type="email" name="email" /><br />
<input type="password" name="password" /><br/>
<!--<input type="submit" value="log in" />-->
<button class="g-recaptcha" data-sitekey="6LdK..." data-callback="onSubmit">log in</button>
</form>
<div id="status"></div>
我的 javascript (jQuery):
<script>
function onSubmit(token){
document.getElementById("myForm").submit();
}
$(document).ready(function(){
$("#myForm").submit(function(event){
event.preventDefault();
var datas = $("#myForm").serialize();
$.ajax({
type: "POST",
url: "test.php",
data: datas,
dataType: "json",
beforeSend: function(){
$("#status").html("logging in...");
},
success: function(response){
$("#status").html(response.text);
if(response.type=="success"){
window.location.replace("/myaccount");
}
},
error: function(){
$("#status").html("Failed.");
}
});
});
});
</script>
ReCaptcha 需要设置一个 "data-callback",我不确定如何绑定我已经存在的“.submit(function(event)”函数。
我的 "onSubmit()" 技巧没有奏效,它忽略 "ajax" 并刷新页面。
如何将 "datas" 变量中的 "g-recaptcha-response" 值发送到 POST 到 test.php?
<script defer>
function onSubmit(token) {
var f = $("#myForm");
$.ajax({
type: "POST",
url: "test.php",
data: f.serialize(),
dataType: "json",
beforeSend: function(){
$("#status").html("logging in...");
},
success: function(response){
$("#status").html(response.text);
if(response.type=="success"){
window.location.replace("/myaccount");
} else {
$("#status").html("Captcha failed.");
}
},
error: function(){
$("#status").html("Failed.");
}
});
}
</script>
在test.php中您需要在服务器端验证验证码:
<?php
if(isset($_POST['g-recaptcha-response'])) {
$result = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret=[YOUR_SECRET_KEY]&response=$_POST["g-recaptcha-response"]&remoteip=$_SERVER["REMOTE_ADDR"]'), TRUE);
if($result['success'] == 1) {
// Captcha ok
} else {
// Captcha failed
}
}
?>
所以这就是我在 Invisible reCAPTCHA 的文档中进一步挖掘并学习了一些 jQuery 之后解决它的方法,显然因为我对 JS(很酷的东西)不是很熟悉:
我的头像带有 javascript 标签(还有一点 css 以移除丑陋的 Google 徽章):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=fr" async defer></script>
<style>
.grecaptcha-badge{
display:none;
}
</style>
<script>
var onloadCallback = function(){
grecaptcha.render("emplacementRecaptcha",{
"sitekey": "YOUR_RECAPTCHA_SITEKEY_HERE",
"badge": "inline",
"type": "image",
"size": "invisible",
"callback": onSubmit
});
};
var onSubmit = function(token){
var userEmail = $("#userEmail").val();
var userPassword = $("#userPassword").val();
var userTfaOtp = $("#userTfaOtp").val();
$.ajax({
type: "POST",
url: location.href,
data:{
userEmail: userEmail,
userPassword: userPassword,
userTfaOtp: userTfaOtp,
userJetonRecaptcha: token
},
dataType: "json",
beforeSend: function(){
$("#statutConnexion").html("Traitement de votre requête d'authentification en cours...");
},
success: function(response){
$("#statutConnexion").html(response.Message);
if(response.Victoire){
$("#formulaireConnexion").slideUp();
window.location.replace("/compte");
}
else{
grecaptcha.reset();
}
},
error: function(){
$("#statutConnexion").html("La communication avec le système d'authentification n'a pas pu être établie. Veuillez réessayer.");
grecaptcha.reset();
}
});
};
function validate(event){
event.preventDefault();
$("#statutConnexion").html("Validation de votre épreuve CAPTCHA en cours...");
grecaptcha.execute();
}
function onload(){
var element = document.getElementById("boutonConnexion");
element.onclick = validate;
}
</script>
HTML:
<div id="formulaireConnexion">
<input type="email" name="userEmail" id="userEmail" placeholder="Courriel" title="Courriel" required="required" /><br />
<input type="password" name="userPassword" id="userPassword" placeholder="Mot de passe" title="Mot de passe" required="required" /><br/>
<input type="text" name="userTfaOtp" id="userTfaOtp" placeholder="Double authentification (optionnelle)" autocomplete="off" pattern="[0-9]{6}" title="Six caractères numériques" maxlength="6" /><br />
<div id="emplacementRecaptcha"></div>
<button id="boutonConnexion">Connexion</button>
</div>
<div id="statutConnexion"></div>
<script>onload();</script>
如果您还需要整个 PHP,请告诉我,因为它超出了这个问题的范围。您可能需要在上面的 JS 中更改 "url: location.href,",因为在我的例子中,渲染 HTML 表单和 JS 以及处理 POST 变量的脚本是相同的(不太好,测试目的)。基本上我只是验证 POST vars 然后最后 return a json like:
$jsonVictoire = true; // boolean
$jsonMessage = 'anything you want to tell your visitor'; // string
$return =
json_encode(
array(
'Victoire'=>$jsonVictoire,
'Message'=>$jsonMessage
)
);
die($return);
<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=onScriptLoad" async defer></script>
<div id="login_page" class="g-recaptcha" data-size="invisible" data-sitekey="your sitekey" data-callback="login_page"></div>
<script>
window.onScriptLoad = function () {
// this callback will be called by recaptcah/api.js once its loaded. If we used
// render=explicit as param in script src, then we can explicitly render reCaptcha at this point
// element to "render" invisible captcha in
var htmlEl = document.querySelector('.g-recaptcha');
// option to captcha
var captchaOptions = {
sitekey: 'your site key...',
size: 'invisible',
// reference to an actual function
callback: window.onUserVerified
};
// Only for "invisible" type. if true, will read value from html-element's data-* attribute if its not passed via captchaOptions
var inheritFromDataAttr = true;
// now render
recaptchaId = window.grecaptcha.render(htmlEl, captchaOptions, inheritFromDataAttr);
};
window.onUserVerified = function (token){
Your ajax code....
}
$("#blog_inquiry").click(function(e){
//var gg = grecaptcha.getresponse();
var token = window.grecaptcha.getResponse(recaptchaId);
// if no token, mean user is not validated yet
if (!token) {
window.grecaptcha.execute(recaptchaId);
return;
}
});
</script>`
我正在尝试使用 jQuery 和 "ajax" 请求在表单中实施最新的 ReCaptcha(又名 "invisible" ReCaptcha)。
ReCaptcha 文档:https://developers.google.com/recaptcha/docs/invisible
我的表格:
<form id="myForm" >
<input type="email" name="email" /><br />
<input type="password" name="password" /><br/>
<!--<input type="submit" value="log in" />-->
<button class="g-recaptcha" data-sitekey="6LdK..." data-callback="onSubmit">log in</button>
</form>
<div id="status"></div>
我的 javascript (jQuery):
<script>
function onSubmit(token){
document.getElementById("myForm").submit();
}
$(document).ready(function(){
$("#myForm").submit(function(event){
event.preventDefault();
var datas = $("#myForm").serialize();
$.ajax({
type: "POST",
url: "test.php",
data: datas,
dataType: "json",
beforeSend: function(){
$("#status").html("logging in...");
},
success: function(response){
$("#status").html(response.text);
if(response.type=="success"){
window.location.replace("/myaccount");
}
},
error: function(){
$("#status").html("Failed.");
}
});
});
});
</script>
ReCaptcha 需要设置一个 "data-callback",我不确定如何绑定我已经存在的“.submit(function(event)”函数。
我的 "onSubmit()" 技巧没有奏效,它忽略 "ajax" 并刷新页面。
如何将 "datas" 变量中的 "g-recaptcha-response" 值发送到 POST 到 test.php?
<script defer>
function onSubmit(token) {
var f = $("#myForm");
$.ajax({
type: "POST",
url: "test.php",
data: f.serialize(),
dataType: "json",
beforeSend: function(){
$("#status").html("logging in...");
},
success: function(response){
$("#status").html(response.text);
if(response.type=="success"){
window.location.replace("/myaccount");
} else {
$("#status").html("Captcha failed.");
}
},
error: function(){
$("#status").html("Failed.");
}
});
}
</script>
在test.php中您需要在服务器端验证验证码:
<?php
if(isset($_POST['g-recaptcha-response'])) {
$result = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret=[YOUR_SECRET_KEY]&response=$_POST["g-recaptcha-response"]&remoteip=$_SERVER["REMOTE_ADDR"]'), TRUE);
if($result['success'] == 1) {
// Captcha ok
} else {
// Captcha failed
}
}
?>
所以这就是我在 Invisible reCAPTCHA 的文档中进一步挖掘并学习了一些 jQuery 之后解决它的方法,显然因为我对 JS(很酷的东西)不是很熟悉:
我的头像带有 javascript 标签(还有一点 css 以移除丑陋的 Google 徽章):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=fr" async defer></script>
<style>
.grecaptcha-badge{
display:none;
}
</style>
<script>
var onloadCallback = function(){
grecaptcha.render("emplacementRecaptcha",{
"sitekey": "YOUR_RECAPTCHA_SITEKEY_HERE",
"badge": "inline",
"type": "image",
"size": "invisible",
"callback": onSubmit
});
};
var onSubmit = function(token){
var userEmail = $("#userEmail").val();
var userPassword = $("#userPassword").val();
var userTfaOtp = $("#userTfaOtp").val();
$.ajax({
type: "POST",
url: location.href,
data:{
userEmail: userEmail,
userPassword: userPassword,
userTfaOtp: userTfaOtp,
userJetonRecaptcha: token
},
dataType: "json",
beforeSend: function(){
$("#statutConnexion").html("Traitement de votre requête d'authentification en cours...");
},
success: function(response){
$("#statutConnexion").html(response.Message);
if(response.Victoire){
$("#formulaireConnexion").slideUp();
window.location.replace("/compte");
}
else{
grecaptcha.reset();
}
},
error: function(){
$("#statutConnexion").html("La communication avec le système d'authentification n'a pas pu être établie. Veuillez réessayer.");
grecaptcha.reset();
}
});
};
function validate(event){
event.preventDefault();
$("#statutConnexion").html("Validation de votre épreuve CAPTCHA en cours...");
grecaptcha.execute();
}
function onload(){
var element = document.getElementById("boutonConnexion");
element.onclick = validate;
}
</script>
HTML:
<div id="formulaireConnexion">
<input type="email" name="userEmail" id="userEmail" placeholder="Courriel" title="Courriel" required="required" /><br />
<input type="password" name="userPassword" id="userPassword" placeholder="Mot de passe" title="Mot de passe" required="required" /><br/>
<input type="text" name="userTfaOtp" id="userTfaOtp" placeholder="Double authentification (optionnelle)" autocomplete="off" pattern="[0-9]{6}" title="Six caractères numériques" maxlength="6" /><br />
<div id="emplacementRecaptcha"></div>
<button id="boutonConnexion">Connexion</button>
</div>
<div id="statutConnexion"></div>
<script>onload();</script>
如果您还需要整个 PHP,请告诉我,因为它超出了这个问题的范围。您可能需要在上面的 JS 中更改 "url: location.href,",因为在我的例子中,渲染 HTML 表单和 JS 以及处理 POST 变量的脚本是相同的(不太好,测试目的)。基本上我只是验证 POST vars 然后最后 return a json like:
$jsonVictoire = true; // boolean
$jsonMessage = 'anything you want to tell your visitor'; // string
$return =
json_encode(
array(
'Victoire'=>$jsonVictoire,
'Message'=>$jsonMessage
)
);
die($return);
<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=onScriptLoad" async defer></script>
<div id="login_page" class="g-recaptcha" data-size="invisible" data-sitekey="your sitekey" data-callback="login_page"></div>
<script>
window.onScriptLoad = function () {
// this callback will be called by recaptcah/api.js once its loaded. If we used
// render=explicit as param in script src, then we can explicitly render reCaptcha at this point
// element to "render" invisible captcha in
var htmlEl = document.querySelector('.g-recaptcha');
// option to captcha
var captchaOptions = {
sitekey: 'your site key...',
size: 'invisible',
// reference to an actual function
callback: window.onUserVerified
};
// Only for "invisible" type. if true, will read value from html-element's data-* attribute if its not passed via captchaOptions
var inheritFromDataAttr = true;
// now render
recaptchaId = window.grecaptcha.render(htmlEl, captchaOptions, inheritFromDataAttr);
};
window.onUserVerified = function (token){
Your ajax code....
}
$("#blog_inquiry").click(function(e){
//var gg = grecaptcha.getresponse();
var token = window.grecaptcha.getResponse(recaptchaId);
// if no token, mean user is not validated yet
if (!token) {
window.grecaptcha.execute(recaptchaId);
return;
}
});
</script>`