I have a working form with captcha. When I load up the webpage and click on submit without checking the box , the alert shows (click on robot), but then if I let the captcha expire and click submit again, the alert doesn't pop up any more. Is there something wrong in the following code or any way to rewrite it?
<script>
window.onload = function() {
var recaptcha = document.forms["form"]["g-recaptcha-response"];
recaptcha.required = true;
recaptcha.oninvalid = function(e) {
alert("Please click on i am not a robot");
}
}
</script>
<script src="https://www.google.com/recaptcha/api.js"></script>
<div class="g-recaptcha" data-sitekey="xxx" data-callback="recaptcha"></div>
Please take a look at my server side php. I tried to add data expired callback several times in past few days but couldn't make it work.
$recaptcha_secret = "xxx";
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$recaptcha_secret."&response=".$_POST['g-recaptcha-response']);
$response = json_decode($response, true);
if($response["success"] === true) {
mail($to, $subject, $body, "From:" . $email);
}
else
{
return false;
}
echo 'success';
}
Re-captcha provides callback handlers when ever user select the checkbox and when checked token got expired. for e.g
<div class="g-recaptcha" id="headerCaptcha" data-callback="recaptchaCallbackHeader" data-expired-callback="recaptchaExpiryHeader" data-sitekey="xxx"></div>
// There should be expiry handler like
function recaptchaExpiryHeader(){
alert('You should have to check captcah again as it is expired');
}
More about the same
Related
Hi i am trying to implement notifications when certain event happens in PHP. Suppose a user is changing its password and after the form is submitted the action takes it to update.php, if the password was succesfully changed the page will redirect to change.php?err=1 where 1 has a noty notification which shows password changed succesfully. If there was some problem it redirects to change.php?err=2.
The code for updating password in update.php :-
$sql="UPDATE user_credentials SET password=? WHERE id=?";
$stmt = $result->prepare($sql);
$stmt->bind_param("si", $hash,$id);
if($stmt->execute()) {
header('Location: ../change.php?err=1');
}
else {
header('Location: ../change.php?err=2');
}
The below code for is for showing messages in change.php.
if(isset($_GET['err']))
{
$error_id = $_GET['err'];
if ($error_id == 1) {
echo "<script> noty({text: 'Password Changed Successfully',layout: 'topRight',timeout: 2500,closeWith: ['click', 'hover'],type: 'success'});</script>";
}
else
if ($error_id == 2) {
echo "<script> noty({text: 'Something went wrong',layout: 'topRight',timeout: 2500,closeWith: ['click', 'hover'],type: 'success'});</script>";
}
}
Now if the page is refereshed it will show the message again and again. I want to show the message only when it is redirected not on refreshes.
I thought of a workaround using sessions like this:-
if ($error_id == 1) {
if(!isset($_SESSION['notify'])) {
$_SESSION['notify'] = TRUE;
echo "<script> noty({text: 'Password Changed Successfully',layout: 'topRight',timeout: 2500,closeWith: ['click', 'hover'],type: 'success'});</script>";
}
}
But it stops the message on refreshes but it doesn't show when page is redirected.
I am just starting to learn php so please let me know what I am doing wrong or what else could be better way to solving this problem. Any help is highly appreciated.
Well in addition to
if(isset($_GET['err'])){}
you can add:
if(isset($_GET['err']) && $_SERVER['HTTP_REFERER'] == YOUR_PREV_PAGE){}
In your case it is update.php
This kind of functionality typically works best when you use an ajax call, that means: without refreshing the page.
You could call update.php in the background (see docs of the link pasted above), and decide in the callback of that ajax function what notification to show, based on the response of your update.php script.
EDIT: simple example
$.ajax({
url: "/update-password.php",
data: {
user: "some-user",
pass: "new-pass"
}
}).done(function(response) {
// Show notification, decide on contents based on response
});
Use SESSION instead of GET for error messages. Set an error at the time it's detected, prior to your header() call:
session_start();
$sql="UPDATE user_credentials SET password=? WHERE id=?";
$stmt = $result->prepare($sql);
$stmt->bind_param("si", $hash,$id);
if($stmt->execute()) {
$_SESSION['error'] = "You password was changed.";
header('Location: ../change.php');
}
else {
$_SESSION['error'] = "We could not change your password.";
header('Location: ../change.php');
}
In change.php (and in any other page were a message might be set), do something similar to this:
session_start();
if (strlen($_SESSION['error'])) {
echo $_SESSION['error'];
$_SESSION['error'] = false;
}
Relevant page here:
http://marcmurray.net/test_sites/cans/news.php
I've been trying to load a message confirmation modal for a while after the user submits an email, but can't get it to work at all.
So far I've tried echoing the whole script out, triggering the script, and changing the hash in the URL and checking for that, which has worked in other areas of the site.
Adding functions like alerts and echoing text onto the page is working fine, but when I use the show method it doesn't work. That leads me to believe I am either escaping characters wrong, or misunderstand how modals work a little.
Can anyone see where I'm messing up?
PHP:
<?php
if(isset($_POST["submit"])) {
// Checking For Blank Fields..
if($_POST["vname"]==""||$_POST["vemail"]==""||$_POST["sub"]==""||$_POST["msg"]==""){
echo "Please fill out everything! We need to know who you are, and why you want to get in touch with us!";}
else
{
// Check if the "Sender's Email" input field is filled out
$email=$_POST['vemail'];
// Sanitize E-mail Address
$email =filter_var($email, FILTER_SANITIZE_EMAIL);
// Validate E-mail Address
$email= filter_var($email, FILTER_VALIDATE_EMAIL);
$emailConfirmed=$_POST['vemail'];
if (!$email){
echo "Don't forget to include your email adress! Otherwise we can't get back to you.";
}
else
{
$subject = $_POST['sub'];
$message = $_POST['msg'];
$headers = 'From:' . $emailConfirmed . "\r\n"; // Sender's Email
$headers .= 'Cc:' . $emailConfirmed . "\r\n"; // Carbon copy to Sender
// Message lines should not exceed 70 characters (PHP rule), so wrap it
$message = wordwrap($message, 70);
// Send Mail By PHP Mail Function
mail("marc.murray.92#gmail.com", $subject, $message, $headers);
echo "<script>$('#thankyouModal').modal('show')</script>";
};
}
}
?>
HTML for the modal
<div class="modal fade" id="thankyouModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Thank you for pre-registering!</h4>
</div>
<div class="modal-body">
<p>Thanks for getting in touch!</p>
</div>
</div>
</div>
</div>
EDIT: Updated code to be simpler than initial question.
Instead of calling modal show method upfront let all the assets load first then call the modal show method.
echo "<script>
$(window).load(function(){
$('#thankyouModal').modal('show');
});
</script>";
Instead of echoing the script why not just detect your form submit with javascript and then display the modal?
Something like
$("form").on('submit', function(){
$('.modal').show();
})
(If you're using JQuery)
First problem i see in your example code is, unnecessary \ on following code.echo "<script> \. Remove it
Second: Are you including all required js and css files for boostrap modal? If you are not Please update the code with following lines of code
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
At last there is no event triggered to open boostrap modal. Add following code to trigger the modal.
$(window).load(function(){
$('#myModal').modal('show');
});
Final code :
echo "<script>
var newHTML = document.createElement ('div');
newHTML.innerHTML =
newHTML = document.createElement ('div');
newHTML.innerHTML = ' <div id=\"myModal\" class=\"modal fade\" tabindex=\"-1\" role=\"dialog\"> <div class=\"modal-dialog\"><div class=\"modal-content\"><div class=\"modal-header\"></div>';
document.body.appendChild (newHTML);
$(window).load(function(){
$('#myModal').modal('show');
});
</script>";
Hope this helps.
I discovered that .in (sets opacity to 1) class which I believe should be set by Bootstrap does not show after submitting the form.
$('.modal').show().addClass('in');
Btw. you have an error in console
$(...).parsley(...).on is not a function
Maybe this is the problem..
echo "<script>$('#thankyouModal').modal('show')</script>";
I would do this....
$var = "<script>$(document).ready(function(){
$('#thankyouModal').modal('show')
});</script>";
And later print it on the right part inside your head at your html template.
Using your option and adding $(document).ready inside the script you are echoing dont think would work...the problem with the last option is that you will echo the script but jquery might not be yet fully loaded and it wont recognize it.
So, I suggest it to send it as a parameter and then print it.
If you are not using a framework and it is hard for you to pass a parameter, you can do it thought the URL and do something like my project.com/result.php?submit=true
and at your frontend you will read that variable
Like
if(isset($_GET["submit"]) && ($_GET["submit"]) ){
//echo your modal script
}
As xkcd149 says, if you mean to load the modal in the same page without reloading, you should be using AJAX requests:
replace the onsubmit attribute of the form to a function that sends the request data
window.onload = function() {
var forms = document.getElementsByTagName("form");
for(var f in forms) {
frm[f].onsubmit = xhr; // xhr is the function that sends the XHR
}
}
in the submit funcion used above, add success and error callbacks:
function xhr(){
var client = new XMLHttpRequest();
...
client.onerror = xhrerr;
client.onreadystatechange = handler;
client.send(...);
...
}
the success function should display the modal if the returned HTTP code is 200 (or whatever you want/need)
function handler(){
if (this.readyState == 4 && this.status == 200) {
var widget = document.getElementById("modal-body");
// add content to the body of the modal
} else {
// manage error
}
}
$('#thankyouModal').submit(function(e) {
e.preventDefault(); // don't submit multiple times
this.submit(); // use the native submit method of the form element
$('#thankyouModal').modal('show'); //Open the model
});
or You can manually create a button after form submit and trigger click on that button to open the modal.
$('#thankyouModal').click(function(e) {
e.preventDefault(); // don't submit multiple times
$("form").submit(); // use the native submit method of the form element
$('<button type="button" id="btnThankYou" class="hidden" data-toggle="modal" data-target="#thankyouModal">ThankYouButton</button>').appendTo('body');
//This will click the button and open the modal
$("#btnThankYou" ).trigger("click");
});
Place this links at your HEAD tag:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
and then change this:
<script>$('#thankyouModal').modal('show')</script>
to:
$(document).ready(function(){
<script>$('#thankyouModal').modal('show')</script>
});
$modal = "<script>$(document).ready(function(){
$('#thankyouModal').modal('show')
});</script>";
if(isset($_GET["submit"]) && ($_GET["submit"]) ){
// after running other script
echo $modal;
}
You can try as
$('#thankyouModal').submit(function(e) {
e.preventDefault(); // don't submit multiple times
this.submit(); // use the native submit method of the form element
$('#thankyouModal').modal('show'); //Open the model
});
Maybe you should send form via ajax, so after submit event you don't have to refresh your page.
As long as you won't refresh your page, your modal will be load successfully.
<?php
if(isset($_POST["submit"])) {
// Checking For Blank Fields..
$checkpost = false;
if($_POST["vname"]==""||$_POST["vemail"]==""||$_POST["sub"]==""||$_POST["msg"]==""){
echo "Please fill out everything! We need to know who you are, and why you want to get in touch with us!";}
else
{
// Check if the "Sender's Email" input field is filled out
$email=$_POST['vemail'];
// Sanitize E-mail Address
$email =filter_var($email, FILTER_SANITIZE_EMAIL);
// Validate E-mail Address
$email= filter_var($email, FILTER_VALIDATE_EMAIL);
$emailConfirmed=$_POST['vemail'];
if (!$email){
echo "Don't forget to include your email adress! Otherwise we can't get back to you.";
}
else
{
$checkpost = true;
$subject = $_POST['sub'];
$message = $_POST['msg'];
$headers = 'From:' . $emailConfirmed . "\r\n"; // Sender's Email
$headers .= 'Cc:' . $emailConfirmed . "\r\n"; // Carbon copy to Sender
// Message lines should not exceed 70 characters (PHP rule), so wrap it
$message = wordwrap($message, 70);
// Send Mail By PHP Mail Function
mail("marc.murray.92#gmail.com", $subject, $message, $headers);
echo "<script>$('#thankyouModal').modal('show')</script>";
};
}
}
?>
in html
<?php if($checkpost){ ?>
<script>
$('.modal').show();
</script>
<?php } ?>
I know it's a bit too late to answer. But hopefully it might help others.
The below code worked for me where I am using a Post-Redirect-Get pattern.Open a modal after form submission.
window.onpageshow = function() {
if (typeof window.performance != "undefined"
&& window.performance.navigation.type === 0) {
$('#myModal').modal('show');
}
}
Write down the following code.If you are using JQuery.
success: function(data)
{
$("#myModal").modal("show");
}
I have managed to get ReCaptcha 2.0 working in my website. However, it's only working when I don't use AJAX and I let the form submit "naturally".
I want to submit the form with the captcha and alert the user with a success note without refreshing the page.
I tried the following code, but it seems like the server doesn't get the user response:
HTML:
<form class="form" action="javascript:void(0)" novalidate>
<!-- all the inputs... -->
<!-- captcha -->
<div class="input-group">
<div class="g-recaptcha" data-sitekey="6LdOPgYTAAAAAE3ltWQGar80KUavaR-JblgPZjDI"></div>
</div>
<div class="errors" id="errors" style="display: none"></div>
<div class="input-group">
<input type="button" value="Send" class="btn-default right" id="submit">
<div class="clear"></div>
</div>
</form>
JS:
$('#submit').click(function(e) {
console.log('clicked submit'); // --> works
var $errors = $('#errors'),
$status = $('#status'),
name = $('#name').val().replace(/<|>/g, ""), // prevent xss
email = $('#email').val().replace(/<|>/g, ""),
msg = $('#message').val().replace(/<|>/g, "");
if (name == '' || email == '' || msg == '') {
valid = false;
errors = "All fields are required.";
}
// pretty sure the problem is here
console.log('captcha response: ' + grecaptcha.getResponse()); // --> captcha response:
if (!errors) {
// hide the errors
$errors.slideUp();
// ajax to the php file to send the mail
$.ajax({
type: "POST",
url: "http://orenurbach.com/assets/sendmail.php",
data: "email=" + email + "&name=" + name + "&msg=" + msg + "&g-recaptcha-response=" + grecaptcha.getResponse()
}).done(function(status) {
if (status == "ok") {
// slide down the "ok" message to the user
$status.text('Thanks! Your message has been sent, and I will contact you soon.');
$status.slideDown();
// clear the form fields
$('#name').val('');
$('#email').val('');
$('#message').val('');
}
});
} else {
$errors.text(errors);
$errors.slideDown();
}
});
PHP:
<?php
// assemble the message from the POST fields
// getting the captcha
$captcha = '';
if (isset($_POST['g-recaptcha-response']))
$captcha = $_POST['g-recaptcha-response'];
echo 'captcha: '.$captcha;
if (!$captcha)
echo 'The captcha has not been checked.';
// handling the captcha and checking if it's ok
$secret = 'MY_SECRET';
$response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']), true);
var_dump($response);
// if the captcha is cleared with google, send the mail and echo ok.
if ($response['success'] != false) {
// send the actual mail
#mail($email_to, $subject, $finalMsg);
// the echo goes back to the ajax, so the user can know if everything is ok
echo 'ok';
} else {
echo 'not ok';
}
?>
The result in the PHP page:
captcha: The captcha has not been checked.array(2) { ["success"]=> bool(false) ["error-codes"]=> array(1) { [0]=> string(22) "missing-input-response" } } not ok
Bottom line is, how can I get the input response manually without it automatically going with the rest of the POST data?
Ok, this was pretty silly.
I have done a couple of things wrong:
In the PHP file, all the strings had single quotes on them, and that caused problems.
Throughout the testing, I added multiple printings of things in the PHP file, thus the if (status == "ok") was never working. I did get the emails but did not get any conformation that I did and now I see why.
When I wanted to check what the PHP file was omitting, I simply went to it's address in the URL and always got an error. Even when the mails were sent. Now I understand that that is not the correct way of checking the logs.
Thanks to #Samurai who helped my figure out things.
Final PHP code:
<?php
// assemble the message from the POST fields
// getting the captcha
$captcha = "";
if (isset($_POST["g-recaptcha-response"]))
$captcha = $_POST["g-recaptcha-response"];
if (!$captcha)
echo "not ok";
// handling the captcha and checking if it's ok
$secret = "MY_SECRET";
$response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER["REMOTE_ADDR"]), true);
// if the captcha is cleared with google, send the mail and echo ok.
if ($response["success"] != false) {
// send the actual mail
#mail($email_to, $subject, $finalMsg);
// the echo goes back to the ajax, so the user can know if everything is ok
echo "ok";
} else {
echo "not ok";
}
?>
I'm trying to have the mail.php script identify the page that called the script, and return the user to that page and if the form didn't validate, was empty, etc. When I click on submit, it just 404's.
<?php
/*
This first bit sets the email address that you want the form to be submitted to.
You will need to change this value to a valid email address that you can access.
*/
$webmaster_email = "email#email.com";
/*
This next bit loads the form field data into variables.
If you add a form field, you will need to add it here.
*/
$email_address = $_REQUEST['email'];
$comments = $_REQUEST['comment'];
$fname = $_REQUEST['first-name'];
$lname = $_REQUEST['last-name'];
$filename = debug_backtrace();
$page = $filename[0]['file'];
/*
The following function checks for email injection.
Specifically, it checks for carriage returns - typically used by spammers to inject a CC list.
*/
function isInjected($str) {
$injections = array('(\n+)',
'(\r+)',
'(\t+)',
'(%0A+)',
'(%0D+)',
'(%08+)',
'(%09+)'
);
$inject = join('|', $injections);
$inject = "/$inject/i";
if(preg_match($inject,$str)) {
return true;
}
else {
return false;
}
}
// If the user tries to access this script directly, redirect them to the feedback form,
if (!isset($_REQUEST['email_address'])) {
header( "Location: $page" );
}
// If the form fields are empty, redirect to the error page.
elseif (empty($email_address) || empty($comments) || empty($fname)) {
echo "<script type=\"text/javascript\">window.alert('Please fill in the required fields.');
window.location.href = $page;</script>";
exit;
}
// If email injection is detected, redirect to the error page.
elseif (isInjected($email_address)){
echo "<script type=\"text/javascript\">window.alert('Please, Try Again.');
window.location.href = $page;</script>";
exit;
}
// If we passed all previous tests, send the email then redirect to the thank you page.
else {
mail("$webmaster_email", "Feedback Form Results", $comments, "From: $email_address");
echo "<script type=\"text/javascript\">window.alert('Thank You for contacting us!');
window.location.href = $page;</script>";
exit;
}
?>
No need for debug_backtrace(). To get the referring page, you could replace this:
$filename = debug_backtrace();
$page = $filename[0]['file'];
With this:
$page = $_SERVER['HTTP_REFERER'];
However, $_SERVER['HTTP_REFERER'] is unreliable according to the PHP docs:
This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.
So another solution is to add an additional field in the referring form and retrieve it in the PHP script e.g.
<input name="referrer" type="hidden" value="<?php echo $_SERVER['PHP_SELF'];?>"/>
Then:
$page = $_REQUEST['referrer'];
I have two questions but they are interrelated. Firstly I am trying to make my form fields required. I have accomplished this but it seems my form still calls my php script when the blank form is submitted. How can I make my validation not call the php script if the form is empty?
Secondly, I want to store the url of an image into my database. How can I submit a pre determined string into my database? I have only accomplished database submission with forms.
Here is my validation and attempt to send the string to the php script.
function validateForm()
{
var x=document.forms["subform"]["school"].value;
var y=document.forms["subform"]["confession"].value;
if (x==null || x=="" || y==null || y=="")
{
alert("Please complete the form before submitting your confession.");
return false;
}
if(x=="CWU"){
$.post('test3.php', $("images/colleges/cwu.png").serialize(), function(data) {
$('#content').html(data);});
}
}
Here is the php script which I am attempting to submit to the image column in the test table.
<?php
// Create connection
$con=mysqli_connect("localhost","root","","test");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql="INSERT INTO test (image)
VALUE
('$_POST[image]')";
if (!mysqli_query($con,$sql))
{
die('Error: ' . mysqli_error($con));
}
echo "image added";
?>
If you want to prevent a form from submitting on the client-side before it can even get to the server, you could do something like this:
$('#myform').submit(function(e) {
var input = $('#myform input').val();
if(input == '') {
//won't allow the form to submit
e.preventDefault();
} else {
//do something
}
});
If you want to implement it on the server-side with PHP, you could do something like this:
$input = $_POST['val'];
if(!empty($input)) {
//carry out the request
} else {
echo "You did not fill out the form!"
}
If you went with the server-side option, it would probably be best implemented in an AJAX environment so that the user doesn't even leave the page when the form is submitted, and then get an error message. This would disrupt the flow a little bit.