Google reCAPTCHA fail for second time submit - javascript

I implement the reCAPTCHA in this tutorial,
https://codeforgeek.com/2014/12/google-recaptcha-tutorial/
which work well for the first time submit. The problems I have are:
I send the captcha with other form data e.g. username , email etc.... so if captcha is correct but other not , the user will send it again, but the second time it return "{ "success": false }"
if I idle it for ~2 min , it will session expire and if I select the box it pop up alert and warning something like " can not refresh : invalid parameter", and I can not select the box again
How to fix those problem? Thanks a lot.

Google reCAPTCHA gives these two functions: I always use this in all my AJAX powered forms.
grecaptcha.getResponse()
grecaptcha.reset();
For both of your problems, use the second function whenever you need in your JavaScript code.
Remember this works if you have only one CAPTCHA in your page. If you have more than two CAPTCHAs use their IDs as explained in Google Docs
https://developers.google.com/recaptcha/docs/display#js_api

Those who have the same problem and meet this topic during research;
If you experience problem when you render the captcha automatically, try to render it explicitly. In order to do this, add following code inside body tag.
<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaCallback&render=explicit&hl=tr" async defer></script>
var recaptchaCallback = function () {
// alert("grecaptcha is ready!");
grecaptcha.render("YOUR HTML DIV ID", {
'sitekey': 'YOUR SITE KEY',
});
};
I'm using AJAX to check registration form and get response. So I have added reset function to my AJAX response.
$('#frmRegistration').submit(function () {
$.ajax({
url: "_ajax/_ajaxRegistration.php",
type: "POST",
data: $('#frmRegistration').serialize(),
success: function (reply) {
$('#resultRegistration').html(reply);
grecaptcha.reset();
}
});
});
Reference Google reCaptcha explicit render.

Related

Google Recaptcha V3 double submit issue (timeout-or-duplicate error)

I have an issue somewhat similar to this scenario :
I got "timeout-or-duplicate" error using ReCaptcha v3
In may scenario i have a form and a button that perfrom submit of the form. Inside the form a setInterval keep the recaptcha fresh :
<script src="https://www.google.com/recaptcha/api.js?render=<%=ServiceLocator.AppConfigProvider.Instance.RecaptchaPublicKey%>"></script>
<script>
onSetupDone(function () {
getReCaptcha();
setInterval(function () { getReCaptcha(); }, 90000);
function getReCaptcha() {
grecaptcha.ready(function () {
grecaptcha.execute('<%=ServiceLocator.AppConfigProvider.Instance.RecaptchaPublicKey%>', { action: globals.currentPage }).then(function (token) {
document.getElementById("reCAPTCHAResponse").value = token;
});
});
};
/**
* Get a previously stored RecaptchaToken
* */
window.getReCaptchaValue = function () {
var result = document.getElementById("reCAPTCHAResponse").value;
getReCaptcha();//refresh the value
return result;
};
});
</script>
the OnSetupDone() is a function equivalent to document ready (it's called once per page, when document is ready and all setup phase is done).
My problem is that when user click twice the button that cause form submit, multiple form are submitted (and then cancelled when a next click occured)
But if the cancellation occurred only after the server use of recaptcha token, i end up using a token twice. And so request is declined (timeout-or-duplicate error).
What is not clear to me is which is the whay to handle situation like that (avoid use a recaptcha token twice in a from submit).
Should i add an handler in the form submit event and take another captcha? (this does not guarantee me that the next submit will be processed after the form sumbit event enqueued by javascript.. so i guess answer is still no)
PS : as shown in the picture, the page (an asp.net page) does not reload while the submit is processed. This also contribute to the fact that the old token is retained by the alredy submitted form.

POST works with alert message but doesn't without it

I am making a post request to google app script with the code below
var url ="MY WEBAPP EXEC"
function submitForm() {
var postRequest = {}
postRequest.name = $("#inputName").val();
postRequest.email = $("#inputEmail1").val();
postRequest.message = $("#inputMessage").val();
alert(JSON.stringify(postRequest)); // this alert
$.post(url, postRequest, function(data,status){
alert('success')
});
}
I am very confused why the post is working with the alert but doesn't work without it. Thank you.
===
OK I guess my question was not clear enough sorry.
I have a form accessing GAS remotely. I assumed the url implied that I was accessing GAS remotely. At the moment I am working on my localhost and on my JS above it works if the alert statement is present and does not do anything if alert is not there.
I was watching the execution list on GSuite Developer Hub to see if the request failed or completed. I observed if the alert statement is in the script the execution status is completed but if the alert statement is not there nothing happens. I assume that my post script is not working if alert is not there. Any idea why?
You haven't shown exactly how that function is called, but it's likely to be because, if this is truly a "form submit" action, the result of submitting a form is to "load a new page" (which can be the same page you're on, and is so by default with no action attribute in the form tag
Since you want to perform AJAX on form submit, you need to "prevent" the "default" form submit action - this can be achieved as shown in the second and third lines below
var url ="MY WEBAPP EXEC"
function submitForm(e) { // if this function is called using an event handler, it gets an event as the first and only argument
e.preventDefault(); // prevent the "default" form submit action
var postRequest = {}
postRequest.name = $("#inputName").val();
postRequest.email = $("#inputEmail1").val();
postRequest.message = $("#inputMessage").val();
alert(JSON.stringify(postRequest)); // this alert
$.post(url, postRequest, function(data,status){
alert('success')
});
}

document.getElementById(..) gives null even though element is present

I have the following program in which a user can enter any name in a search box after which I redirect the user to a page called usernameSearchResults.php where I print a list of the usernames obtained in the form of an array from usernamesearch.php. Here is the javascript:
$(window).on('load', function() {
$(".searchBarForm").submit(function(e){
e.preventDefault();
var search=document.getElementsByClassName("search")[0].value;
$.ajax
({
type: 'POST',
url: 'usernamesearch.php',
data:
{
search:search
},
success: function (response)
{
window.location.href="usernameSearchResults.php";
response = JSON.parse(response);
var array_length = Object.keys(response).length;//getting array length
for(var i=0;i<array_length;i++){
if(i==0){
document.getElementById("searchResults").innerHTML=""+response[0].username+"<br>";//i=0
}else{
document.getElementById("searchResults").innerHTML+=""+response[i].username+"<br>";
}
}
window.stop();//stops page from refreshing any further(put here to fix a bug that was occuring)
},
error: function(xhr, status, error) {
alert(xhr.responseText);
}
});
return false;
})
});
This is usernameSearchResults.php(inside tags):
<h1>Username Search Results</h1>
<p id="searchResults"></p>
But the problem is that whenever I go to any other page say index.php and enter the username to be searched, the page redirected to is indeed usernameSearchResults.php but the page is blank and error in the console shown says document.getElementById("searchResults") is null.But if I stay at the page usernameSearchResults.php and refresh it and then search any name again, then the results are correctly obtained. What is the problem here?
I would say that the user is being redirected to usernameSearchResults.php but the JavaScript code is still being executed from the current page, which have no element with id "searchResults" defined.
As #Kashkain said, one way to achieve what you want is to pass your response variable in your redirection url and process it then into your other page.
I think the problem here is that the new document could very well still not have been loaded when you call getElementById.
You could add a listener on your target element which would trigger on the load event. In this event's handler you could execute the operations that are now giving you an error.
I have never done or tried this, but maybe something like this would work:
$('#searchResults').on('load', function() {
//execute code here
});
Or you could add a form to the page with action="target_url" method="post" and send your response data through post by doing form.submit, and place the problematic code into usernameSearchResults.php, which will need to read data from POST - this way you can send your ajax data to the new page

Trouble updating a <div> after successful validation using jQuery Validation plug-in

I am validating a form using the jQuery Validation plug-in, and I'm having some trouble updating a <div> with the status once the form is submitted (called using submitHandler). Once the user clicks to submit the form, it should update the #inviteStatus element with a status ("Adding user"). Then, once the response is received from the server (1-2 seconds) it should update #inviteStatus again with a result ("Success" or "Fail"). However, my script is jumping directly to the latter update ("Success" or "Fail"), and skipping the first "Adding user" update.
http://jsfiddle.net/bhall7x/Mf7sq/4/
I tried inserting a delay(5000); after the first <div> update, but the script seems to just stop at that point, and never continues on to the second result update message.
Any ideas why this is happening? Thanks!
UPDATE: I've created an updated Fiddle that has the actual code that I'm using. I can't get the .ajax() query to actually work on JS Fiddle, but this way you can see what I'm trying to accomplish. Basically, I'd like to first update #inviteStatus, show it, then
update it with the results of my .ajax() query. Here's the code I'm using in the submitHandler of the jQuery Validation plug-in after the form is successfully validated:
// form successfully validated, provide user notification
$("#inviteStatus").html("<div class=\"alert alert-info\">Adding user</div>");
$("#inviteStatus").show(500);
// get form values
var postData = $(form).serializeArray();
// submit form
$.ajax({
type : "POST",
data : postData,
async : false,
cache : false,
url : "inviteScript.php",
success: function(result) {
// Provide the results of the ajax call
$("#friendInviteStatus").html(result);
$("#friendInviteStatus").show(500).delay(5000).hide(500);
}
});
You need to add an anonymous function to the show() call instead of altering the html on a different line.
$("#inviteStatus").show(500);
// submit form here via ajax() call
$("#inviteStatus").html("<div class=\"alert alert-success\">Success!</div>");
Should be
$("#inviteStatus").show(500,function() {
// submit form here via ajax() call
$("#inviteStatus").html("<div class=\"alert alert-success\">Success!</div>");
});
http://jsfiddle.net/Mf7sq/7/
it is working fine, to simulate the ajax you need to give a delay
// Form actions
$("#addForm").validate({
debug: true,
rules: {
invitee: "required"
},
messages: {
invitee: "Please enter a username"
},
submitHandler: function (form) {
$("#inviteStatus").html("<div class=\"alert alert-info\">Adding user</div>");
$("#inviteStatus").show(500);
// submit form here via ajax() call
//simulate the ajx call
setTimeout(function () {
$("#inviteStatus").html("<div class=\"alert alert-success\">Success!</div>");
$("#inviteStatus").show(500).delay(5000).hide(500);
}, 2000)
}
});
Demo: Fiddle
Another slightly modified version is http://jsfiddle.net/arunpjohny/9jLb5/2/ - It is not recommended since it delays sending the ajax request till the message is completely shown
I was actually able to get this to work by removing the async:false on the .ajax() call.

Checking for duplicate username

I am doing a registration page, for my mobile app, and want to check for duplicate usernames entered by the user/client
I have a button on the page that when clicked, checks availability of the username. However I would like to also incorporate that automatically, if not already done so, when the client clicks submit/go to step 3,
I want to perform the check for duplicate usernames using Ajax and if there exists a duplicate, then refresh the SAME page with the error message for duplication, else proceed to step 3.
In my HTML file I have some js that does the following:
$("#check-username").click(function() {
(...this works as I am able to click the CHECK button
and see if the username exists)
I have another js file, that is sourced in my HTML that does the following:
submitHandler : function() {
$("#reg1").hide();
$("span#step").html("2");
$("#check-username").click;
$("#reg3").show();
scrollTop();
}
When I click on Go to next step which is reg3, It does not do the validation for check-username. Is my method/syntax for calling check-username correct?
$("#check-username").click;
^^----- Missing Braces
supposed to be
$("#check-username").click();
The problem is you need to go to step 3 only after the validation ajax request returns from the server. You also are going to need to look at the response from the server to see if it's a duplicate. For example:
$("#check-username").click(function() {
validateUser();
});
function validateUser(){
return $.ajax({
url: '/path/to/validate'
});
}
And your submit handler stuff:
submitHandler : function() {
$("#reg1").hide();
$("span#step").html("2");
validateUser()
.done(function(r){
//for example...
if(r.isValidUser){
$("#reg3").show();
scrollTop();
}
});
}

Categories