Problems getting data from AJAX to PHP (and back) - javascript

The idea is that this script POSTs the value of the text input in my html form to emailform.php, which takes that data and adds it to a .txt file. I think what I'm having trouble with is setting the value of $email in the PHP to that of the html text input. As a result, currently when the script is triggered I get two alerts (first 'error' then 'complete', from the .fail and .complete functions) and then the page reloads. That's why I think the problem is with the information being returned from the PHP but maybe I'm wrong.
<form method="post">
<input type="text" name="email" value="" class="emailSubmitSidebar" placeholder=" Your Email">
<input type="submit" name="submit" value="Add" class="submitButton" id="subscribeButton">
</form>
<script type='text/javascript'>
$(document).ready(function() {
var subscribeButton = $('#subscribeButton');
subscribeButton.click(function() {
$.ajax({
url: 'emailform.php',
type: 'POST',
dataType: 'text',
data: {email: $("input[name=email]").val()},
})
.done(function(data) {
alert("Added!");
})
.fail(function() {
alert("error");
})
.always(function() {
alert("complete");
})
})
})
</script>
And below is the PHP, I've added the first two lines to check for any errors, of which there are none anymore. What's strange is that when I run the PHP separately, the echo line prints the number 3 on the page without any apparent cause. I commented out the variable $email because I was led to believe it was better/necessary to first check if it isset.
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$fileHandle = fopen('emailList.txt', 'a') OR die ("Can't open file\n");
$email= isset($_POST['email']) ? $_POST['email'] : "";
// $email=$_POST['email'];
$result = fwrite ($fileHandle, "$email; \n");
fclose($fileHandle);
echo (!$result) ? "error" : $result;
die;
?>

I think there is something wrong with your data, try to serialize it into a json data array:
var data = $(form).serialize();
$.ajax({
url: 'emailform.php',
type: 'POST',
dataType: 'text',
data: data,
})
The values will be sent as a normal post request, so the email address will be in $_POST['email'];
Updated from here
The jquery .done() and .fail() functions require http status codes to work, so your php file should return these codes. When a request is made and succeeded anything in the 200 range will be ok. While on an error, something from the 400 or 500 range should be returned. There is a full list here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
So the ajax .success function is fired when 2xx is returned (replace .done with .success) and the .error is called when status code 4xx or 5xx is returned. See php below how to implement this.
The number 3 you are getting is the $return value of the fwrite function, according to: http://nl3.php.net/fwrite
fwrite() returns the number of bytes written, or FALSE on error.
Make your php like this:
<?php
//ini_set('display_errors', 'On');
//error_reporting(E_ALL);
if($fileHandle = fopen('emailList.txt', 'a')) {
if(isset($_POST['email']) && !empty($_POST['email'])) {
$email = $_POST['email'];
$result = fwrite ($fileHandle, "$email; \n");
fclose($fileHandle);
if(isset($result) && !empty($result)) { // Something was written
http_response_code(200);
echo "File written";
} else { // Writing failed
http_response_code(500);
echo "Writing of file failed";
}
} else { // Empty email
http_response_code(500);
echo "Email was empty";
}
} else { // File could not be opened
http_response_code(500);
echo "File could not be opened for writing";
}
?>

(Simple)
Change HTML to:
<input type="text" name="email" value="" class="emailSubmitSidebar" placeholder=" Your Email">
Change JS to :
$.ajax({
url: 'emailform.php',
type: 'POST',
dataType: 'text',
data: {email: $("input[name=email]").val()}
})
.done(function(data) {
// there checking
alert("success!")
})
Change PHP to:
$fileHandle = fopen('emailList.txt', 'a') OR die ("Can't open file\n");
$email=$_POST["email"];
$result = fwrite ($fileHandle, "$email; <br/>");
fclose($fileHandle);
echo (!$result)? "error" : $result;
die;

Related

AJAX serialized data empty

I'm trying to post form data via AJAX.
When I remove the AJAX function and do a standard form POST method the data is being inserted into DB fine. When I console.log the serialized data of the form on submit it shows fine.
It's when the AJAX function is fired that the data seemingly disappears. The function fires as a success but no data is inserted and the formdata variable is seemingly empty. Can anyone shine any light on this?
Here's the code so far -
jQuery/AJAX -
$('#calendar-form').submit(function() {
var formdata = $(this).serialize();
console.log(formdata);
$.ajax({
url: "insert.php",
type: "POST",
data: formdata,
success: function() {
alert('success')
},
error: function() {
alert('ERROR');
}
});
return false;
});
HTML
<form id="calendar-form" action="" method="" accept-charset="utf-8">
<input type="text" name="name" id="name">
<input type="text" name="email" id="email">
<input type="hidden" name="site" id="site" value="<? echo $_SERVER['HTTP_HOST'] ?>">
<input class="submit" type="submit" name="submit" value="Submit">
</form>
PHP
try {
$bd = new PDO("mysql:host=localhost;dbname=;charset=utf8", "", "");
// $bd->setAttribute(PDO::ATT_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Theres been an error while attempting to connect to the database';
}
if(isset($_POST['submit'])){
$name = $_POST['name'];
$email = $_POST['email'];
$site = $_POST['site'];
$sql = "INSERT INTO `users`(`name`, `email`, `site`) VALUES ('$name', '$email', '$site')";
try {
$query = $bd->prepare($sql);
$query->bindValue(':name', $name, PDO::PARAM_STR);
$query->bindValue(':email', $email, PDO::PARAM_STR);
$query->bindValue(':site', $site, PDO::PARAM_STR);
if($query->execute()){
echo "Success";
}else{
echo "Failure";
}
} catch (Exception $e) {
echo $e->getMessage();
}
}
Note: I've removed DB details for this post but they're there in code.
Console
name=Benji&email=email%40email.com&site=localhost%3A8888 - scripts.min.js:9:117
Network
This is because jQuery's .serialize() does not include the submit button:
No submit button value is serialized since the form was not submitted using a button.
Check the console for the output of your console.log(formdata) - you'll see submit is missing. And since it is missing, the test you do on that value on the back end will fail:
if(isset($_POST['submit'])){
Exactly how to do solve this depends on what you're trying to do. If you just want to make sure the request was a POST (not a GET) you could use:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
If you want to do basic validation, you could explicitly check each of the expected values are present:
if (isset($_POST['name']) && isset($_POST['email']) && isset($_POST['site'])) {

My server side php doesn't get the data from my client side AJAX requiest

Here is my AJAX code:
$("#loginbutton").click(function(){
var email = $('#email').val();
var password = $('#password').val();
$.ajax({
url: 'login.php',
type: 'POST',
dataType: 'json',
data: { email:email, password:password},
success: function(data){
$("#samplediv").innerHTML ="Welcome";
}
});
});
And this is my PHP:
<?php
session_start();
$conn = mysqli_connect("localhost", "root", "", "getpet");
if(isset($_POST['email'])){
echo $_POST['email'];
}
?>
As you can see it will be a login system, but the php doesn't write out the $_POST['email']
variable. I think it is probably a syntax mistake, just I am too blind. I would really appreciate it if somebody can help me.
UPDATE:
Here is my whole php code, i think it's not relevant, but this is ther reason, why i use dataType: json.
<?php
session_start();
$conn = mysqli_connect("localhost", "root", "", "getpet");
if(isset($_POST['email'])){
echo $_POST['email'];
}/*
$results = array(
'success' => false,
'user_id' => "azaz",
'fname' => "",
'lname' => ""
);
if(!empty($_POST['email']) && !empty($_POST['password'])){
$email = $_POST['email'];
$password = md5($_POST['password']);
$sql= "SELECT * FROM users WHERE email = '$email' AND password = '$password'";
$rowsql = mysqli_query($conn, $sql);
$row = mysqli_fetch_array($rowsql, MYSQLI_BOTH);
if(mysqli_num_rows($rowsql) == "1"){
$_SESSION['user_id'] = $row['user_id'];
$_SESSION['fname'] = $row['fname'];
$_SESSION['lname'] = $row['lname'];
$results['success'] = true;
$results['user_id'] = $row['user_id'];
$results['fname'] = $row['fname'];
$results['lname'] = $row['lname'];
}
}
//echo json_encode($results);*/
?>
In your data object, your keys are not strings, but the variables that you have defined. Do it like that to have email and password taken literally:
data: { 'email':email, 'password':password},
i think this is a cross origin problem, but normaly this is shown in console. append a error ouput to your json and look for it, if it's a php error you will get noticed now.
$.ajax({
url: 'login.php',
type: 'POST',
dataType: 'json',
data: { email:email, password:password},
success: function(data){
$("#samplediv").innerHTML ="Welcome";
},
error: function (jqXHR, textStatus, errorThrown) {{
console.error('ajax response failed');
console.log(jqXHR.responseText);
}
});
$("#samplediv").innerHTML ="Welcome"; is wrong
you have a jquery element here and try to access with vanilla functions.
$("#samplediv").text("Welcome");
// or
$("#samplediv")[0].innerHTML = "Welcome";
if you open your browsers dev tools it should show you the error:
innerHTML is not a function of ...
-> make sure you call jQuery though :)
-> added document ready
-> added prevent default
-> use input instead of button is only my convenience
<script type="text/javascript">
$(document).ready( function() { /* only when everything is set up */
$("#loginbutton").click(function(e){
e.preventDefault();
var email = $('#email').val();
var password = $('#password').val();
$.ajax({
url: "login.php",
method: "POST", /* changed to `method` */
data: "email="+email+"&password="+password, /* MODIFIED */
success: function(data){
alert(data);
$("#samplediv").html("Welcome !");
},
error: function (request, status, error) { /* added error handling */
alert(request.responseText);
}
});
});
});
</script>
<div id="samplediv"></div>
<form action="#" id="form" method="post">
<p><input type="text" name="email" id="email" value="" /> email</p>
<p><input type="text" name="password" id="password" value="" /> pwd</p>
<input type="submit" id="loginbutton" value="GO" />
</form>
of course, make the input password type !
As I don't know why you connect (possible select ?) with DB, I just made php file simple, as follows :
<?php
/* login.php */
error_reporting(E_ALL); ini_set('display_errors', 1);
$email = $_POST['email'];
$pwd = $_POST['password'];
echo"[ email > $email / pwd : $pwd ]"; /* for example only, of course, not with real credentials */
?>
after edit of the original question, I saw php code and I would recommand
NOT using MD5 anymore but password_hash / password_verify
you should really consider using PPS : Prepared Parameterized Statements. This will help Preventing SQL injection

Redirect from Ajax's PHP script

I have a form like this:
<form action="process.php" method="post">
<input type="text" name="input" />
<button type="submit">Submit</button>
</form>
And I have an Ajax script like this:
$("button").click(function(event) {
var $ajaxData = {
"input-val" : $("input").val();
}
$.ajax({
type : "POST",
url : "process.php",
data : $ajaxData,
dataType : "json",
encode : true
});
.done(function($data) {
alert($data["stat"]);
});
event.preventDefault();
$("form").unbind();
});
Also a PHP script (process.php) where the form data is send:
<?php
if(isset($_POST['input-val'])) {
$data['stat'] = 'success';
echo json_encode($data);
}
?>
All is correct and set, but, if I want to stop the users of seeing or going (manually) to the "process.php" page I add a redirect function:
<?php
if(isset($_POST['input-val'])) {
$data['stat'] = 'success';
echo json_encode($data);
}
header('Location: index.php');
?>
That makes Ajax's request fail automatically. How can I stop users of going or seeing the PHP script?
As I said, the "event.preventDefault();" is stopping Ajax of sending the users to the PHP script, but users can go there by themselves.
The problem is, the script is expecting a JSON, while your "redirect" code sends a HTTP 301 to a HTML file. Ultimately, the AJAX XHR is not seeing your JSON, but gets the HTML output.
Revert back your code to how it was before:
<?php
if(isset($_POST['input-val'])) {
$data['stat'] = 'success';
echo json_encode($data);
}
Instead, do it in the AJAX handler:
.done(function($data) {
alert($data["stat"]);
if ($data["stat"] == "success")
location.href = 'index.php';
}) // And you are also missing a ) here.
According to comments:
If you are redirecting if the $_POST is not set, please use the else:
if (isset($_POST['input-val'])) {
$data['stat'] = 'success';
echo json_encode($data);
} else {
header('Location: index.php');
}

AJAX form submission, solely to prevent page refresh and nothing else

I've built a simple HTML/PHP e-mail sign-up form to appear in the footer area of my website. There are only two fields: email and country.
The form works perfectly for my purposes. Data collection, validation, sanitization, error handling, clear fields, success notification, etc. -- ALL GOOD!
My final step is to implement AJAX to prevent a page refresh. This is all that is required from AJAX.
All tutorials, articles, and answers to related questions on this site I have found offer code that includes functions I've already handled with PHP.
I've gotten as far as the AJAX submission, which works. The page doesn't refresh, user input is inserted to the database, and I receive the confirmation e-mail.
I would appreciate some guidance (or a link to a tutorial) that can help me implement the PHP error logic and echo PHP success/error messages.
HTML
<form action="process_footer_form/" method="post" id="footer-form">
<ul>
<li>
<input type="email" name="email" id="email"
value="<?php if (isset($email)) {echo $email;} ?>">
</li>
<li>
<input type="text" name="country" id="country"
value="<?php if (isset($country)) {echo $country;} ?>">
</li>
<li>
<input type="submit" name="submit" id="submit">
</li>
</ul>
<?php if (isset($success_message)) {echo $success_message;} ?>
<?php if (isset($error_message)) {echo $error_message;} ?>
</form>
JQuery
$(function() {
// identify form
var form = $('#footer-form');
// create event listener
$(form).submit(function(event) {
// disable html submit button
event.preventDefault();
// serialize form data
var formData = $(form).serialize();
// submit form using AJAX
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData
})
.done(function(response) {
// 1. echo PHP success message
// 2. fire PHP clear fields command
})
.fail(function(data) {
// 3. execute PHP error logic here
// 4. echo PHP error messages
});
});
});
PHP
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Load PHPMailer
require 'PHPMailer/PHPMailerAutoload.php';
// Create PHPMailer session
$mail = new PHPMailer;
$mail->CharSet = "UTF-8";
// SMTP settings
$mail->isSMTP();
$mail->Host = 'smtp.xxxxxxxxxx.com';
$mail->SMTPAuth = true;
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
$mail->Username = 'xxxxxxxxxxxxxxxxxx';
$mail->Password = 'xxxxxxxxxxxxxxxxxx';
$mail->setFrom('xxxxxxxxxxxxxxxxxx' , 'xxxxxxxxxxxxxxxxxx');
$mail->addAddress('xxxxxxxxxxxxxxxxxx');
$mail->isHTML(true);
// Sanitize & Validate Input
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$country = trim(filter_input(INPUT_POST, 'country', FILTER_SANITIZE_SPECIAL_CHARS));
// set connection to mysql server
$connection = mysql_connect("localhost","xxxxxxxxxxxxxxxxxx","xxxxxxxxxxxxxxxxxx");
// connect to database
mysql_select_db("xxxxxxxxxxxxxxxxxx", $connection);
// insert user input to table
$sql = "INSERT INTO email_subscribers (email,country) VALUES ('$email','$country')";
if (!$connection) {
$error_message = <<<ERROR
<div>ERROR. Form not sent. Please try again or contact us.</div>
ERROR;
// Send error notice to host
$mail->Subject = 'Website Error - Footer Form';
$mail->Body = ("Error Notice: A site user is having trouble on the footer form.");
$mail->send();
} else {
// run query
mysql_query($sql, $connection);
$success_message = <<<CONFIRMATION
<div>Subscription complete. Thank you!</div>
CONFIRMATION;
mysql_close($connection);
// Send confirmation notice to host.
$message = <<<HTML
<span>E-mail: {$email}</span><br>
<span>Country: {$country}</span>
HTML;
$mail->Subject = 'New E-mail Subscriber - Footer Form';
$mail->Body = $message;
$mail->send();
unset($email, $country);
}
} else {
header('Location: http://www.mywebsite.com/');
exit;
}
?>
You might try simplifying your life by using the FormData object. Then your code could look something like this. I have tested this out.
<form method="POST" id="subscription-form" enctype="multipart/form-data">
<input type="email" name="email" id="email" value="gulliver#tinyletter.com">
<input type="text" name="country" id="country" value="Lilliput">
<input type="button" value="submit" id="form-submit">
</form>
Below this you could put in a div for displaying messages:
<div id="messages"></div>
Then your jquery/javascript would look something like this:
<script>
(function(){
$("#form-submit").on("click", function(){ submitForm();});
})();
function submitForm(){
var form = document.getElementById("subscription-form");
var fd = new FormData(form);
$.ajax({
url: './PHPscript.php',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
$("#messages").html(data);
}
});
}
</script>
Regarding letting PHP "handle the messages" I think you're missing something about AJAX.
In your initial PHP page you are loading the html that PHP has generated and then PHPs part is finished. When you make the AJAX call you are asking the server to execute a different PHP script and then return the output of that script back to javascript.
At that point you need to put whatever message PHP has generated back into the current page, which has not and will not reload. That was the purpose of using AJAX in the first place. That is what the "messages" div is for.
As a way of completely understanding this create an extremely simple PHPscript.php file that looks like this and try it out:
<?php
print $_POST['email'] . ' ' . $_POST['country'];
?>
You will see your values returned in the current page inside that messages div.
The first request to, for example www.mysite.com/something.php will run the PHP and dump the result into the page. Ajax doesn't work this way. You send a request to your PHP file, and it sends a response that you can then inspect and do something with.
If ajax responses dumped their content into the page like an initial load, mayhem would ensue.
Try something like this:
$.ajax({
url: url,
type: type,
data: data
}).done(function (response) {
console.log(response);
});
then have a looksie in the console and see what goodness you're getting from the PHP script. Then build that .done callback up to process the results of your request and determine what to do.
Okay, first thing, var that = this is a trick when you loses context, but where you use it is not somewhere you can lose it .. so forget it :)
Then your find().each(), it's a good way of getting your values, but jquery offers a method which is $( this ).serializeArray() (it does kinda exactly what your want)
Also, you send your data with ajax, but you have no callback. Your ajax call need to have at least a function to call once everything went fine. This is done with done()
Finally, returning false does cancel the event in most cases but you will prefer preventDefault() as it disable default behavior, but still propagate event (for other handlers).
Sum it all:
$('form.ajax').submit( function(event) {
var form = $(this);
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: form.serializeArray()
}).done(function(data) {
alert("Ajax call successful");
console.log("Server answer:" + data);
});
event.preventDefault();
});
Edit: Nvm my first remark, I understood lately your that = this stuff.

Ajax connection to function in php failing

I am trying to submit a form via ajax but it doesn't let me:
Ajax - samepage
<script type="text/javascript">
$(document).on('submit','.subscribe',function(e) {
$.ajax({ url: 'lib/common-functions.php',
data: {action: 'subscribe'},
type: 'post',
success: function(output) {
alert(output);
}
});
});
</script>
HTML - same page
<form class="subscribe">
<label class="lablabel">Name:</label><input type="text" class="subscribe-field" id="sname" name="sname"></br>
<label class="lablabel">Email:</label><input type="text" class="subscribe-field" id="semail" name="semail" >
<input type="submit" id="ssub" value="Subscribe">
</form>
PHP - common-functions.php
<?php
require_once('dbconn.php');
function subscribe() {
$name = $_POST['sname'];
$email = $_POST['semail'];
$db->query("INSERT INTO subscribers (`name`, `email`, 'confirmed') VALUES ($sname, $email, 0)");
echo "You have been subscribed";
}
?>
EDIT added dbconn
$db = new mysqli($dbhostname, $dbuser, $dbpass, $dbname);
if ($db->connect_errno) {
echo "Failed to connect to MySQL: (" . $db->connect_errno . ") " . $db->connect_error;
}
In the console I get nothing. After I click submit and check the console. I can see in red how is actioning common-functions.php but doesn't do anything. Please help.
TL;DR You need to do six things to fix the problems in the code you have provided. There are pitfalls with event propagation, scoping, and variable validation.
First, add this to your JavaScript: event.preventDefault(); event.stopPropagation();.
Second, submit your actual data.
Example showing these fixes:
$(document).on('submit','.subscribe',function(e) {
e.preventDefault(); // add here
e.stopPropagation(); // add here
$.ajax({ url: 'lib/common-functions.php',
data: {action: 'subscribe',
sname: $("#sname").val(),
semail: $("#semail").val()},
type: 'post',
success: function(output) {
alert(output);
}
});
});
Third, actually call subscribe().
Fourth, you have a scoping problem: $db is a global, but you don't refer to it as one. That's why I added global $db; below.
Fifth, check the existence of your POST values.
Sixth, put quotes around your database values and escape them first.
<?php
require_once('dbconn.php');
function subscribe() {
global $db;
if(isset($_POST['semail'], $_POST['sname'])) {
$name = $_POST['sname'];
$email = $_POST['semail'];
$db->query("INSERT INTO subscribers (`name`, `email`, 'confirmed') VALUES ('".$db->escape_string($sname)."', '".$db->escape_string($email)."', 0)");
echo "You have been subscribed";
}
}
subscribe();
?>
NOTE: This just shows how to fix the code that you have posted. The code in the question, however, is wide open to SQL injection. You really should use prepared statements instead of relying on escaping of special characters.
You have to include the data youre accessing via Post in PHP in the data object in the $.ajax call:
$.ajax({ url: 'lib/common-functions.php',
data: {action: 'subscribe',
sname: $("#name").val()
semail: $("#semail").val()},
type: 'post',
success: function(output) {
alert(output);
}
});
});
Also your PHP function subscribe doesnt get called just by setting action:"subscribe"
You have to check wheter $_POST["action"] is "subscribe":
if($_POST["action"]=="subscribe")
{
subscribe();
}

Categories