form action redirect from JS (reCaptcha) - javascript

I have a submit form, after checking the captcha v3, I need to send the form with the same values. how to do this after receiving the token from the captcha?
With the code below, either a human or a bot outputs to the browser console, but does not redirect to the desired page
.then(result => {
if (result['om_score'] >= 0.5) {
console.log('Human')
} else {
console.log('Bot')
}
});
If i use window.location = "mail.php"; insted of console.log it send empty request
My goal is that the redirect would be to the <from> action with the entered values.

You can use JS to submit the form. Suppose you have the following form:
<form id="myform" action="mail.php" method="post">
....
</form>
You can use JS to submit it:
....
.then(result => {
if (result['om_score'] >= 0.5) {
console.log('Human')
document.getElementById("myform").submit();
} else {
console.log('Bot')
}
});
As a side note, you shouldn't be checking the Captcha client-side because it can easily be spoofed.

Related

How to show alerts on bad request, but redirect on success?

I have a registration form, the user is being redirected to home.php after success (works)
But also all the 'alerts/errors' which are echos in PHP, after submit, will redirect to register.php and show the error in blank white page.
(How do i display them to <div class="msg"> position?)
<script>
document.querySelector(".register form").addEventListener("submit", async (e) => {
e.preventDefault()
const form = e.target
const body = new FormData(form)
// fetch is much easier to use than XHR
const res = await fetch(form.action, {
method: "POST",
headers: {accept: "application/json", // let PHP know what type of response we want},
body})
const data = await res.json()
if (res.ok) {
location.href = data.location
} else if (res.status === 400) {
document.querySelector('.msg').textContent = data.message
// also do something with data.errors maybe
}
})
</script>
<body>
<div class="msg"></div> <!--position for error/ wrong pass etc-->
register.php
Based off that, please provide a correct code snippet in order to mark this as resolved.
It would probably make your life quite a bit easier if you always returned JSON from your PHP, rather than sometimes HTML as well.
For examples, when checking the errors at the top of register.php, you should return JSON objects --- e.g.
{error: "Email is not valid!"}
rather than their HTML equivilents.
This means that in your fetch, you'll now always be able to get the JSON content (currently, you'd probably get an error in your browser's debug console if one of those messages came back, as it's not valid JSON). Then, in your JavaScript, you can just detect this and switch however you want:
if (data.error) { // If there is an error
document.querySelector(".msg").textContent = data.error;
}
else if (data.location) { // If we want to redirect the user somewhere
window.location.href = "./" + data.location;
}

reCaptcha V3 fails validation on first form submission only

I am trying to set up reCaptcha v3 and it sort of works. For some reason the first time I submit the form it fails but from the second submit onwards it is fine. I can't figure out why this is happening?
<script src="https://www.google.com/recaptcha/api.js?render=MY_SITE_KEY"></script>
<script>
grecaptcha.ready(function () {
grecaptcha.execute('MY_SITE_KEY', { action: 'contact' }).then(function (token) {
var recaptchaResponse = document.getElementById('captcha-response');
recaptchaResponse.value = token;
});
});
</script>
<input type="hidden" name="captcha-response" id="captcha-response">
PHP
$verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$_POST['captcha-response']);
$responseData = json_decode($verifyResponse);
if(!$responseData->score < 0.5) {
$message .= "Verification failed " . $responseData->score;
}
When I submit the form the first time, I get the validation error but my score is 0.9.
Why you have added "!" with "$responseData->score"? you may need to replace your condition with the following:
Replace this:
if(!$responseData->score < 0.5) {
$message .= "Verification failed " . $responseData->score;
}
With this one:
if($responseData->score < 0.5) {
$message .= "Verification failed " . $responseData->score;
}
P.S: Following code takes few seconds to properly load and get a "captcha-reponse" code, so you may need to disable all submit button and wait till you got a "captcha-reponse" to enable the submit button in form or you needs to implementent another way to delay the submit to execute only once you got a "captcha-response" code otherwise you will keep getting "missing-input-response" error message
<script src="https://www.google.com/recaptcha/api.js?render=MY_SITE_KEY"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('MY_SITE_KEY', {
action: 'contact'
}).then(function(token) {
var recaptchaResponse = document.getElementById('captcha-response');
recaptchaResponse.value = token;
});
});
</script>
You should re-generate the reCaptcha token after error form validation occured.
The token reCaptcha only valid for ONE TIME.
So, you have two options to fixes this issue.
1. Reload the page when error occured
This is the easiest way. You only need to reload the page whenever form validation error occured.
Of course, this will trigger the reCaptcha to generate new token.
2. Handle with AJAX (Non-reload page)
This is the best approach, since this will helps the user not losing the form data and continue to fill the form.
So, here's what you should do.
<!-- Put this hidden input inside of your form tag -->
<input name="_recaptcha" type="hidden">
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITEKEY_HERE"></script>
<script>
// This will generate reCaptcha token and set to input hidden
const generateRecaptcha = function() {
grecaptcha.execute(
"YOUR_SITEKEY_HERE", {
action: "YOUR_ACTION_NAME"
}).then(function(token) {
if (token) {
document.querySelector("input[name='_recaptcha']").value = token;
}
});
}
// Call it when page successfully loaded
grecaptcha.ready(function() {
generateRecaptcha();
});
// Do your AJAX code here
$.ajax({
url: "https://example.com",
success: function(response) {
console.log(response);
},
error: function(error) {
// Call again the generator token reCaptcha whenever error occured
generateRecaptcha();
}
</script>
Don't forget to put your Site key and your action name. Make sure the action name matches with your Backend action name.
Medium Article

Javascript client get response from server

I fill in a form in html and then submit it.
At first the client validates the data (e.g if the eula checkbox is accepted) and after the client sends the data to the server.
The server checks also the data returns a status code to me.
How can I get this status code from the server?
Here are some example snippets
HTML
<form name="newsletter" method="post" action="/api/newsletter" onsubmit="if(!validate()){return false;} else tryToFetch();">
<input name="name" type="text" id="name"/>
<input name="eula" type="checkbox" id="eula"/>
<input type="submit" name="submit"/> </form>
client js:
function validate() {
if (this.eula.checked == false) { alert ('EULA NOT ACCEPTED'); return false; } else {
return true; }
}
tryToFetch
function tryToFetch(){
fetch('http://localhost:3000/api/newsletter')
.then(function(response) {
console.log(response.status ) ;
});
}
Server.js
app.post('/api/newsletter', urlencodedParser ,function (request, response) {
//Just check some data...
response.statusCode = 999;
response.send('999');
});
Now how can I get the status code 999 in the browser and handle it?
Is it even possible todo only using js?
As written in Fetch documentation :
"The fetch specification differs from jQuery.ajax() in two main ways:
The Promise returned from fetch()won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing."
So maybe this is causing your problem ? Have you tried using default XMLHttpRequest.

Submitting a form and run a function at the same time [duplicate]

This question already has answers here:
Form Submit Execute JavaScript Best Practice? [closed]
(3 answers)
Closed 11 months ago.
When I press the Submit button of a form it runs a php file which stores the answer to a db.
Is it possible to use the Submit button of a form to submit the user's choice and immediately after that run a function without further actions from the user?
For example, in the following simple form and php, how can I run a function when the user presses Submit?
<form action="db.php" method="post">
A:<input type="radio" name="answer" value="A">
B:<input type="radio" name="answer" value="B">
<input type="submit" name="submit value="submit">
</form>
<?php
$con = mysqli_connect('localhost','my user id','my password');
if(!con) {
echo 'not connected to server';
} else {
echo 'something else is wrong';
}
if(!mysqli_select_db($con,'my user id') {
echo 'Database error selection';
}
if (isset($_POST['submit'])) {
$answer=$_POST['answer'];
$sql = INSERT INTO test1 (columnName) VALUES ('$answer');
mysqli_query($con,$sql); // Execute query
}
?>
As an example let's take the following function which is a part of a larger file.
function next() {
var qElems = document.querySelectorAll('#questions>div');
for (var i = 0; i < qElems.length; i++) {
if (qElems[i].style.display != 'none') {
qElems[i].style.display = 'none';
if (i == qElems.length - 1) {
qElems[0].style.display = 'block';
} else {
qElems[i + 1].style.display = 'block';
}
break;
}
}
}
You can add an onsubmit event handler to the form
<form action="db.php" method="post" onsubmit="functionToCall()">
which will call the given function when the form is submitted. If you want to stop the form from being submitted, return false from the function. As #JokerDan said, you can also use AJAX within your function and omit the form action altogether.
function functionToCall() {
// Do something before you submit your form (save data locally or whatever)
var http = new XMLHttpRequest();
http.onreadystatechange = function(){
if(this.readyState == 4 && this.status == 200) {
//Do something after submitting the form (if you want to change the page or redirect)
}
};
http.open('POST', 'db.php');
http.send(/*send post data here*/);
}
If you want to send data with the AJAX request, you will have to pull it from the form and put it in the http.send() line in the same format you pass data in the URL (data=answer&submit=true)
The proper way to do this, is to first select your form using something like document.querySelector or document.getElementById (only possible if the form element has an id).
var form = document.querySelector('[action="db.php"]');
After you selected your form, use the addEventListener of your form to add an evenListener.
form.addEventListener('submit', myListener, false);
Now you'll just need to create a function that looks like this :
function myListener(event) {
// DO STUFF
}
Here, event is an object of type Event that provides more information about the form you submitted. This function will be called every time you try to submit your form!

Redirect on deny of a confirm dialog

My task is to submit a from based on user confirmation. If the user confirm then the form is submitted. If the user deny then the from is redirected to other page. I've a form in jsp like this -
.....
<form id="stageUpdateForm" method="post">
</form>
......
And in javascript I'm trying -
$('#stageUpdateForm').submit(function() {
decision = confirm("Some data changed. Are you sure?");
return decision;
// if user deny then redirect
});
Now if the user deny to submit the from its stay in current page. But I want to redirect the page to other url (eg. - www.google.com) if the user deny. How can I do this?
You want to try something like this:
if (decision) {
window.location = "http://whenever.wherever";
} else {
// Returning false from a submit handler will prevent the submit action.
return false;
}
You can do:
$('#stageUpdateForm').submit(function () {
var decision = confirm('Some data changed. Are you sure?');
// if user deny then redirect
if (!decision) {
$(location).attr('href', 'http://www.google.com');
}
// If user confirm, than it will return true and the form will be sumbited
return decision;
});

Categories

Resources