I am using a third party shopping cart that sends a registration form to a .cgi script.
I want to send information from that form to me, and the customer via a jQuery $.get() function call.
The $.get calls a registration.mail.php script.
The problem is that the form submitting seems to cancel out the ajax call before the ajax call can be completed.
I can think of some inelegant solutions, and I have decided, because I'm about to travel, to use a counter and make the user click 'Register' twice. This solution hurts my soul obviously.
Here's the Javascript, that lives in the footer:
<script type="text/javascript">
var getsuccess = false;
$(document).ready(function() {
$('form#registerWholesale').bind('submit', function() {
$email = $('#email').val();
$username = $('#contactname').val();
$company = $('#company').val();
$phone = $('#billphone1').val();
$message = "A new customer has registered at the wholesale website. \n ";
$message += "They have the username of: " + $username + ". \n";
$message += "Their company is: " + $company + ". \n";
$message += "Their email is: " + $email + ". \n";
$message += "Their phone is: " + $phone + ". \n";
$message += "Please help them ASAP. You can access the back end of the site at: http://location of website admin backend";
$.get('/mail.php', {from: 'orders#OurCompany.com', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
getsuccess = true;
});
if (getsuccess) {
return true;
}else{
return false;
}
});
</script>
And here is the registration.mail.php code.
<?php
//Vendor email (to us)
$to = "ouremail#OurCompany.com";
$subject = "URGENT--New Registration--URGENT";
$message = htmlentities($_GET['message'], ENT_QUOTES, 'UTF-8');
//$message = $_GET['message'];
$from = htmlentities($_GET['from'], ENT_QUOTES, 'UTF-8');
//$from = trim($_GET['from']);
$headers = "From: $from";
mail($to,$subject,$message,$headers);
//echo "Mail Sent.";
//Customer email (to them)
$to_cust = htmlentities($_GET['email'], ENT_QUOTES, 'UTF-8');
$subject_cust = 'OurCompany Online Wholesale Account Request Recieved';
$message_cust = "Thank you for you interest in OurCompany's new wholesale website. \n\n
We have received your request to create an account. In order to obtain a wholesale account, a OurCompany representative must verify your account information and details by telephone. OurCompany will contact you within 1 business day at the telephone number that we have on file, or feel free to give us a call at 1-xxx-xxx-xxxx anytime if you would like a more rapid approval. \n\n
Thanks Again ~ OurCompany";
$headers_cust = "From: orders#OurCompany.com";
mail($to_cust,$subject_cust,$message_cust,$headers_cust)
?>
Thank you!
Your Ajax get handler sets up an asynchronous callback. In other words, this piece of code:
$.get('/mail.php', {from: 'orders#OurCompany.com', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
getsuccess = true; <---- THIS
});
The "THIS" line is only called when the Ajax call returns a result. Since you are sending an actual email, it may take a long time.
So, by the time you run this:
if (getsuccess) {
return true;
}else{
return false;
}
The Ajax call has never completed, and this always returns false.
You should basically just decide whether you want to submit the form with Ajax or not, and only use one of those. If you want to do Ajax, the Submit event handler should always return False.
EDIT: I did not realize that the mail sending and form submitting are two different actions, and two separate server calls. (You are not showing the rest of your app, but this is the idea that I get from other answers.) This is bad design that may lead to inconsistent results and bad data. You should redesign your app so that both of these things are handled on server side in the same place, so that the web app only makes one call, no matter if this one call is by Ajax or regular form submit.
One solution is to bind the event to the button click , prevent the default action of the click so the form does not submit, then finally submit the form in the .get callback.
N.B As Jaanus suggests you should really look at the app design and send the mail and save the cart in the same call. What happens if the email gets sent then the form submission action fails?
$(document).ready(function() {
$('#yourSubmitButton').click( function(ev) {
//prevent form submission
ev.preventDefault();
$email = $('#email').val();
$username = $('#contactname').val();
$company = $('#company').val();
$phone = $('#billphone1').val();
$message = "A new customer has registered at the wholesale website. \n ";
$message += "They have the username of: " + $username + ". \n";
$message += "Their company is: " + $company + ". \n";
$message += "Their email is: " + $email + ". \n";
$message += "Their phone is: " + $phone + ". \n";
$message += "Please help them ASAP. You can access the back end of the site at: http://location of website admin backend";
$.get('/mail.php', {from: 'orders#OurCompany.com', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
//all is well, submit the form
$('#yourForm').submit()
});
});
At the very least, rather than make them click twice, why dont you make the success callback of the $.get submit the form again for them?
$('form#registerWholesale').bind('submit', function() {
if (getsuccess) {
return true;
} else {
$email = $('#email').val();
$username = $('#contactname').val();
$company = $('#company').val();
$phone = $('#billphone1').val();
$message = "A new customer has registered at the wholesale website. \n ";
$message += "They have the username of: " + $username + ". \n";
$message += "Their company is: " + $company + ". \n";
$message += "Their email is: " + $email + ". \n";
$message += "Their phone is: " + $phone + ". \n";
$message += "Please help them ASAP. You can access the back end of the site at: http://location of website admin backend";
$.get('/mail.php', {from: 'orders#OurCompany.com', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
getsuccess = true;
$('form#registerWholesale').submit();
});
return false;
}
});
Have you tried putting the ajax call in a function, and hooking the onSubmit of the form?
onsubmit="myajaxcallFunc(); return true;"
This is commonly used to stop the submission, with return false, but in this case it may do what you want.
The callback you're passing to $.get will be evaluated after the AJAX request. Since AJAX is asynchronous, your code will continue to evaluate in the mean time, which means your if-condition with the two return-statements will always evaluate before the AJAX callback is called.
What you want to do is for the submit listener to always return false, and in the AJAX callback, you conditionally trigger $('form#registerWholesale').submit();
Of course there's a design consideration here as well: you may want the e-mail sending and wholesale registration to be atomical. If the mail is sent, you always want the stuff that happens in form submit to happen as well, right? In that case you want to move either the email sending to the form postback, or the wholesale registration to the AJAX callback, so it's all handled in one step.
Related
I'm working on a contact website, where I want to have contact form. I want it to send data to e-mail and I want it to be checked by Google's recaptcha v3.
This is my second try. In the past, I've done it successfully without recaptcha. Now, I used this (https://codeforgeek.com/google-recaptcha-v3-tutorial/) tutorial, with following result:
script below the form
// when form is submit
$('#myform').submit(function() {
// we stoped it
event.preventDefault();
var mail = $('#email').val();
var comment = $("#sprava").val();
// needs for recaptacha ready
grecaptcha.ready(function() {
// do request for recaptcha token
// response is promise with passed token
grecaptcha.execute('__SITE-KEY__', {action: 'create_comment'}).then(function(token) {
// add token to form
$('#myform').prepend('<input type="hidden" name="g-recaptcha-response" value="' + token + '">');
$.post("form.php",{mail: mail, comment: comment, token: token}, function(result) {
if(result.success) {
alert('Thanks for message')
} else {
alert('An error occured')
}
});
});;
});
});
</script>
the names of html form fields are "email", "vyber", "sprava"
form.php
<?php
$mail;$comment;$captcha;
$mail = filter_input(INPUT_POST, 'mail', FILTER_VALIDATE_EMAIL);
$comment = filter_input(INPUT_POST, 'comment', FILTER_SANITIZE_STRING);
$captcha = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING);
}
function email_sending(){
$webmaster_email = "bla#bla.com";
$sender_email= "blabla#bla.com" ;
$email_address = $_REQUEST['email'] ;
$selection = $_REQUEST['vyber'] ;
$message = $_REQUEST['sprava'];
$msg =
"E-mail: " . $email_address . "\r\n" .
"I'm interested in " . $selection . "\r\n" .
"Message: " . $message ;
mail( "$webmaster_email", "You have mail", $msg, $header);
}
if($responseKeys["success"]) {
echo json_encode(array('success' => 'true'));
email_sending();
} else {
echo json_encode(array('success' => 'false'));
}
?>
The problem isn't within recaptcha part, but then I recieve e-mail, where data is missing. (it shows only variable names, not actual values). I might think it's because of naming in script, as I'm not sure what to write in declaration of variables. I'd be glad to receive any input about this problem.
I managed to solve this problem by changing server-side code like below, thanks to this Recaptcha tutorial.
// Check if form was submitted:
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['recaptcha_response'])) {
// Build POST request:
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = '__SECRET-KEY___';
$recaptcha_response = $_POST['recaptcha_response'];
// Make and decode POST request:
$recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
$recaptcha = json_decode($recaptcha);
// Take action based on the score returned:
if ($recaptcha->success == true) {
// Verified - send email
} else {
// Not verified - show form error
}
}
I am using a form-to-email.php for a contact form in my website, but I don't really understand php code.
The ready-to-use form-to-email.php file has a line "redirect to thank you page," and I have to build a thank you page for the action.
But I hope the UX could be easier like a pop-up thank you message instead of another page.
Anyone could help me to create the lines? Thank you very much!!
Below is the complete code of form-to-email.php, the line "header('Location: thank-you.html')" is the redirect path, and I'm wondering is there any way to modify the lines?
<?php
if(!isset($_POST['submit']))
{
//This page should not be accessed directly. Need to submit the form.
echo "error; you need to submit the form!";
}
$name = $_POST['name'];
$visitor_email = $_POST['email'];
$message = $_POST['message'];
$agree = $_POST['agree'];
//Validate first
if(empty($name)||empty($visitor_email))
{
echo "Name and email are mandatory!";
exit;
}
if(IsInjected($visitor_email))
{
echo "Bad email value!";
exit;
}
$email_from = 'receiver#gmail.com';//<== update the email address
$email_subject = "letter from customer";
$email_body = "$name\n".
"Message:\n$message\nLINE ID: $line".
$to = "receiver#gmail.com";//<== update the email address
$headers = "From: $email_from \r\n";
$headers .= "Reply-To: $visitor_email \r\n";
//Send the email!
mail($to,$email_subject,$email_body,$headers);
//done. redirect to thank-you page.
header('Location: thank-you.html');
// Function to validate against any email injection attempts
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 you want to use JavaScript, you can use this code to show the message "Thank you for your message" in an alert() box:
Replace header('Location: thank-you.html') with:
echo'
<script>
window.onload = function() {
alert("Thank you for your message");
location.href = "index.php";
}
</script>
';
You can also use below AJAX script to handle it. It will not reload the page and it will give you good user experience. You must include jquery library to work.
$.ajax({
url: "ready-to-use form-to-email.php",
type: "post",
data: {id:xyz},
success: function (response) {
// you will get response from your php page (what you echo or print)
alert('Success') ;
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
I have a jquery/ajax contact form and tried to add the Google reCAPTCHA v2, but it isn't working. The form worked before I included the reCAPTCHA. The reCAPTCHA shows up (although it takes forever to load), and I can verify that I'm not a robot (which takes forever as well), but when I click on my submit button, the spot where I display my status messages shows this, including the code, as text:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>500 Internal Server Error</title> </head><body> <h1>Internal Server Error</h1> <p>The server encountered an internal error or misconfiguration and was unable to complete your request.</p> <p>Please contact the server administrator, and inform them of the time the error occurred, and anything you might have done that may have caused the error.</p> <p>More information about this error may be available in the server error log.</p> </body></html>
I can't figure out what's going wrong. I followed Google's instructions and included this just before my tag:
<script src='https://www.google.com/recaptcha/api.js'></script>
and integrated my form like this:
<div class="g-recaptcha" data-sitekey="6LeehAsUAAAAAILDfzizJ23GHH7yPGxWBFP_3tE7"></div>
I tried many different ways to integrate it in my mailer.php file without success, and I couldn't find many tutorials that address v2 specifically (not sure if it even matters). My most recent version of the mailer.php is based on an example I found on Google's recaptcha Github:
<?php
require_once __DIR__ . 'inc/autoload.php';
// If the form was submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// If the Google Recaptcha box was clicked
if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])){
$siteKey = '6LeehAsUAAAAAILDfzizJ23GHH7yPGxWBFP_3tE7';
$secret = 'I-removed-this-for-now';
$recaptcha = new \ReCaptcha\ReCaptcha($secret);
$resp = $recaptcha->verify($gRecaptchaResponse, $remoteIp);
// If the Google Recaptcha check was successful
if ($resp->isSuccess()){
$name = strip_tags(trim($_POST["name"]));
$name = str_replace(array("\r","\n"),array(" "," "),$name);
$email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
$message = trim($_POST["message"]);
if ( empty($name) OR empty($message) OR !filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo "Oops! There was a problem with your submission. Please complete the form and try again.";
exit;
}
$recipient = "I-removed-this#for-now.com";
$subject = "New message from $name";
$email_content = "Name: $name\n";
$email_content .= "Email: $email\n\n";
$email_content .= "Message:\n$message\n";
$email_headers = "From: $name <$email>";
if (mail($recipient, $subject, $email_content, $email_headers)) {
http_response_code(200);
echo "Thank You! Your message has been sent.";
}
else {
http_response_code(500);
echo "Oops! Something went wrong, and we couldn't send your message. Check your email address.";
}
}
// If the Google Recaptcha check was not successful
else {
echo "Robot verification failed. Please try again.";
}
}
// If the Google Recaptcha box was not clicked
else {
echo "Please click the reCAPTCHA box.";
}
}
// If the form was not submitted
// Not a POST request, set a 403 (forbidden) response code.
else {
http_response_code(403);
echo "There was a problem with your submission, please try again.";
}
?>
This is the app.js that goes with my contact form (I haven't changed this at all when trying to include the reCAPTCHA):
$(function() {
// Get the form.
var form = $('#ajax-contact');
// Get the messages div.
var formMessages = $('#form-messages');
// Set up an event listener for the contact form.
$(form).submit(function(e) {
// Stop the browser from submitting the form.
e.preventDefault();
// Serialize the form data.
var formData = $(form).serialize();
// Submit the form using AJAX.
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData
})
.done(function(response) {
// Make sure that the formMessages div has the 'success' class.
$(formMessages).removeClass('error');
$(formMessages).addClass('success');
// Set the message text.
$(formMessages).text(response);
// Clear the form.
$('#name').val('');
$('#email').val('');
$('#message').val('');
})
.fail(function(data) {
// Make sure that the formMessages div has the 'error' class.
$(formMessages).removeClass('success');
$(formMessages).addClass('error');
// Set the message text.
if (data.responseText !== '') {
$(formMessages).text(data.responseText);
} else {
$(formMessages).text('Oops! An error occured, and your message could not be sent.');
}
});
});
});
The autoload.php comes directly from the Google Github, and I didn't make any changes:
<?php
/* An autoloader for ReCaptcha\Foo classes. This should be required()
* by the user before attempting to instantiate any of the ReCaptcha
* classes.
*/
spl_autoload_register(function ($class) {
if (substr($class, 0, 10) !== 'ReCaptcha\\') {
/* If the class does not lie under the "ReCaptcha" namespace,
* then we can exit immediately.
*/
return;
}
/* All of the classes have names like "ReCaptcha\Foo", so we need
* to replace the backslashes with frontslashes if we want the
* name to map directly to a location in the filesystem.
*/
$class = str_replace('\\', '/', $class);
/* First, check under the current directory. It is important that
* we look here first, so that we don't waste time searching for
* test classes in the common case.
*/
$path = dirname(__FILE__).'/'.$class.'.php';
if (is_readable($path)) {
require_once $path;
}
/* If we didn't find what we're looking for already, maybe it's
* a test class?
*/
$path = dirname(__FILE__).'/../tests/'.$class.'.php';
if (is_readable($path)) {
require_once $path;
}
});
I would really appreciate your help!
Okay, I fixed it. One reason it wasn't working was that I had to enable allow_url_fopen in php.ini.
Then I completely changed the code to get rid of that autoload.php and the class error. I didn't change app.js. The working mailer.php now looks like this:
<?php
// If the form was submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// If the Google Recaptcha box was clicked
if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])){
$captcha=$_POST['g-recaptcha-response'];
$response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=MYKEY&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
$obj = json_decode($response);
// If the Google Recaptcha check was successful
if($obj->success == true) {
$name = strip_tags(trim($_POST["name"]));
$name = str_replace(array("\r","\n"),array(" "," "),$name);
$email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
$message = trim($_POST["message"]);
if ( empty($name) OR empty($message) OR !filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo "Oops! There was a problem with your submission. Please complete the form and try again.";
exit;
}
$recipient = "I-removed-this#for-now.com";
$subject = "New message from $name";
$email_content = "Name: $name\n";
$email_content .= "Email: $email\n\n";
$email_content .= "Message:\n$message\n";
$email_headers = "From: $name <$email>";
if (mail($recipient, $subject, $email_content, $email_headers)) {
http_response_code(200);
echo "Thank You! Your message has been sent.";
}
else {
http_response_code(500);
echo "Oops! Something went wrong, and we couldn't send your message. Check your email address.";
}
}
// If the Google Recaptcha check was not successful
else {
echo "Robot verification failed. Please try again.";
}
}
// If the Google Recaptcha box was not clicked
else {
echo "Please click the reCAPTCHA box.";
}
}
// If the form was not submitted
// Not a POST request, set a 403 (forbidden) response code.
else {
http_response_code(403);
echo "There was a problem with your submission, please try again.";
}
?>
I am trying to use the sendmail function in php threw a pop up box. i have gotten as far as making the sendmail function and the pop up to work separately. but i haven't been able to figure out how to connect the sendmail in the right way. below is the last working git version i have. any help would be wonderful.
{
<tr>
<th align="center">Instrument Serial Number:</th>
<td align="left"><input type="text" class="cInstTravText" name="SerialNumber" id="idSerialNumber"/></td>
<button onclick="drop_check()">comfirm</button>
<p id="drop_check"></p>
<script>
function sendEmail()
{
$to = 'jonsrod1992#gmail.com';
$subject = 'Test email using PHP';
$message = "test";
//$message = 'hello world.\n\n this is a test for functionality\n\n this is the first try\n place instrument serial Number here--> '<$modelNumber>'<-- there.';
$headers = 'From: jonr#twobtech.com' . "\r\n" . 'Reply-To: jonr#twobtech.com' . phpversion();
mail($to, $subject, $message, $headers, '-fwebmaster#example.com');
}
function drop_check() {
var x;
if (confirm("transfer and send email!") == true) {
x = "transfered and email sent!";
} else {
x = "You pressed Cancel!";
}
document.getElementById("drop_check").innerHTML = x;
}
</script>
</tr>
The approach you're attempting isn't going to work. The php on your page runs first (server side), and then your pop-up is triggered using JavaScript. This means you'll need to send the response from the pop-up to another php page which then handles the sendmail. You can do this via POST in a form submission, or better yet, using an AJAX call, like so (this goes between script tags, preferably at the top or bottom of your page, not in the middle of your HTML):
if (confirm("transfer and send email!")) {
//if needed, get values from one or more HTML inputs like so:
var stuff = $('#someInputId').val();
$.ajax({
type: "POST",
url: "sendmail.php",
data: { data: stuff } //if you don't need to send any data from your HTML elements this can be ommitted
}).success(function() {
//optional: let the user know email was sent
});
}
You would then put your sendmail code in sendmail.php. If you're sending any data in the AJAX call, you can retrieve it from $_POST. sendmail.php would look something like:
$body = isset($_POST['stuff']) ? $_POST['stuff'] : 'no stuff';
$to = 'jonsrod1992#gmail.com';
$subject = 'Test email using PHP';
$headers = 'From: jonr#twobtech.com' . "\r\n" .
'Reply-To: jonr#twobtech.com' . "\r\n" .
"MIME-Version: 1.0\r\n" .
"Content-Type: text/html; charset=ISO-8859-1\r\n";
mail($to,$subject,$body,$headers);
Maybe I'm missing something, but... it looks like you may be trying to just throw PHP into your javascript. That is not going to work. Also, if this is just weird reformatting of the code, the sendEmail function is not being called.
I have built a form which is submitted via Ajax and then processed with the mail() function in PHP. The form validation and form submission works perfectly (I can console log the data and receive a success message), yet I'm not receiving any emails from my form. I'm assuming it's the process.php.
This is my first time doing this, so also any pointers/code improvements would be much appreciated.
Javascript:
var name = $('#name').val();
var email = $('#email').val();
var message = $('#message').val();
var dataString = 'name=' + name + '&email=' + email + '&message=' + message;
$.ajax({
type: "POST",
url: "process.php",
data: dataString,
success: function () {
alert('success');
}
});
PHP:
<?php
$myemail = "name#example.com";
$subject = "Subject";
$message = "
Name: $name
E-mail: $email
Message: $message
";
mail($myemail, $subject, $message);
?>
I think indeed the problem resides within the php mail() method.
Just make sure it is, by commenting out the mail() call, and replace it with
echo 'I should be sending mail now!';
exit;
Then change your ajax call to:
$.ajax({
type: "POST",
url: "process.php",
data: dataString,
success: function (response) {
alert(response);
}
});
Now send the form to the server, and see what comes up in the alert box.
If you get the expected string, you should indeed setup a smtp server so you can send mail.
Another option would be to use an external mailserver, but it requires you to have a proper email account somewhere else.
There are a bunch of scripts out there, check out phpmailer for instance.
Thanks to dibs and dabs of help, I've managed to work it out.
The Ajax was all good, as expected.
The email wasn't sending because it was running locally, not using my servers mail PHP.
And the data from the form wasn't being referenced, thus returning blank emails.
SO, this is what ended up working:
<?php
$myemail = "name#example.com";
$subject = "Subject";
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$body = "
Name: $name
Email: $email
Message: $message
";
mail($myemail, $subject, $body);
?>