Ajax form only submitting sometimes - php

There are several questions like this on SO but none of the answers have worked for me. I have tried them all.
I tried to minimize the code I am pasting, but it's kind of hard with this script
I have a comment form that is submitted via ajax to a php script which saves the comment and then gets all the comments and redisplays them so the new comment can be displayed without refreshing the page.
Only sometimes will the comments successfully submit to the database and redisplay properly. Usually almost every other submit the comment will be saved. Every other time nothing seems to happen.
My real issue is the comments not being saved every time one is submitted.
Here is the javascript and the ajax call:
$(document).ready(function(){
var working = false;
$('#commentForm').submit(function(e){
if(working) return false;
working = true;
$('#submitComment').val('Working..');
$('span.error').remove();
$.post('/ajax/comment.process.php',$(this).serialize(),function(msg){
working = false;
$('#submitComment').val('Submit');
if(msg.status){
$('#commentArea').slideDown().$(msg.html).prepend('#commentArea');
$('#blogComment').val('');
}
else {
$.each(msg.errors,function(k,v){
$('label[for='+k+']').append('<span class="error">'+v+'</span>');
});
}
},'json');
});
});
and here is the function that submits the comment:
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = $_POST['blogComment'];
$blog_id = intval($_POST['blogID']);
$photoSubmit = $_POST['comPhoto'];
$newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");
if($newComQuery === false) {
echo "Query failed";
}else{
$returnCom = $this->comMarkup($blog_id);
echo $returnCom;
}
}
and here is a piece of the comMarkup() function that echos the comments (it is only the important pieces):
// This method outputs the XHTML markup of the comment
public function comMarkup($blog_id) {
$sql = $this->mysqli->query("SELECT * FROM b_comments WHERE blog_id = '".$blog_id."' ORDER BY date DESC");
while($d = $sql->fetch_assoc()) {
$d = $validate->sanitize($d);
echo "
<div class='comment-block'>
<span class='com-img'><img src='".$photo_path."' /></span>
<h3 style='display: inline;'><a href='".$profile."'>".$userName."</a></h3>
<div class='com-date'>".$d['date']."</div>
<p>".$comContent."</p>
</div>
";
}
}
EDIT: Here is the comment.process.php code as requested:
session_start();
include_once('../classes/comment.class.php');
include_once('../classes/db.class.php');
include_once('../classes/user.class.php');
$user_id = $_SESSION['user_id'];
$db = new DBConnection;
$comments = new Comment($db);
$user = new User($db);
$blogID = intval($_POST['blogID']);
$addCom = $comments->addComment($user_id);
echo json_encode(array('status'=>1,'html'=>$addCom));

Given your description, my guess is that it has something to do with your working variable, and the fact that it is not set to false at the end of your $.post().
But there are a few logic, efficiency, and manageability issues with the way you've drawn up the process. I'd recommend having a look at the official jQuery docs for $.post(), specifically the .done(), .fail(), and .always() chained methods.
I'd also recommend naming your PHP variable something other than $_POST, so it does not become confused with the PHP super global.
Finally, I'd recommend treating your comment as an object and using PDO (this is a link to PDO:query as a kind of "immersion" approach but be sure to read all the docs). It will save you a ton of headaches in database interaction.

It looks like you've got a race condition caused by the working flag. Since you're just using that flag to show the "working..." message and prevent submits while a request is processing, I would just use the normal $.ajax call and put the "working" logic in the beforeSend option. Here's an example:
$(document).ready(function(){
$('#commentForm').submit(function(e){
$.ajax({
type: 'POST'
url: '/ajax/comment.process.php',
dataType: 'json',
beforeSend: function(jqXHR, settings) {
$('#submitComment').val('Working..');
$('span.error').remove();
},
data: $(this).serialize(),
complete: function(jqXHR, textStatus) {
var msg = jqXHR.responseText;
$('#submitComment').val('Submit');
if(msg.status){
$('#commentArea').slideDown().$(msg.html).prepend('#commentArea');
$('#blogComment').val('');
}
else {
$.each(msg.errors,function(k,v){
$('label[for='+k+']').append('<span class="error">'+v+'</span>');
});
}
};
});
});
});

are you using json_encode()? if not all your echo-backs will be received as "text" and not as an json-object which you're accessing in your jquery

I guess you should use encodeURIComponent($('#blogComment').val()) somwhere for passing your blogcomment value to PHP file for insert.
Edit 1:
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = rawurlencode($_POST['blogComment']);
if rawurlencode() did not work. use following function:
function encodeURIComponentNew($str) {
$revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')');
return strtr(rawurlencode($str), $revert);
}
(function from What is the equivalent of JavaScript's encodeURIcomponent in PHP?)
and then
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = encodeURIComponentNew($_POST['blogComment']);

Doubt this is related, but I've had issues in the past when doing ajax stuff using "echo" inside a function, and then trying to echo the returned value again.
Try changing your echo's inside all your functions for "return" instead like so:
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = $_POST['blogComment'];
$blog_id = intval($_POST['blogID']);
$photoSubmit = $_POST['comPhoto'];
$newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");
if($newComQuery === false) {
return "Query failed";
}else{
$returnCom = $this->comMarkup($blog_id);
return $returnCom;
}
}

If the user send a comment with ' maybe will happens an error. When you send a comment, the string will broke a mmysqli_query. It can help you, MAYBE.
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = htmlspecialchars($_POST['blogComment'], ENT_QUOTES);
$blog_id = intval($_POST['blogID']);
$photoSubmit = htmlspecialchars($_POST['comPhoto'], ENT_QUOTES);
$newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");
if($newComQuery === false) {
echo "Query failed";
}else{
$returnCom = $this->comMarkup($blog_id);
echo $returnCom;
}
}

It might cause of Browser cookiess. So that In your URL just add addtional queryString for unique URL pattern.
Example:
$.post('/ajax/comment.process.php?random=randamnumber');

You have a SQL Injection vulnerability in your PHP code, make sure you're escaping your variables properly or use a prepared query.
As for the JS part, make sure to return true; at the end of your .submit() function. (for you it would be after the $.post() call)
Also, your 'working' variable can be set forever to true if there's an error in your php script, which is very likely to happen with the SQL Injection Vuln in place.
Explanation: You set it to true, success callback possibly doesn't get called because of error 500 from PHP Backend, so it never gets set to false by your callback, and then you can't ever submit anymore till next page refresh.

So, if I understand the problem correctly, you're submitting the comment and it's not inserting into the database, and it's also presumably not showing you a database error or printing out your Query failed string?
It seems as though your PHP script isn't being executed at all?
If this is the case, I would normally say the most likely culprit for an intermittent error like this is your browser cache. Your browser is looking at the URL, thinks it already knows what content goes with that URL, and returns that content without ever even sending your info to the server. The simplest way to beat that is to add a random querystring to your file call, e.g.:
cachebuster = new Date();
'/ajax/comment.process.php?cachebuster='.cachebuster.getTime();
... I say "normally" since you're using POST and under "normal" circumstances the browser does not cache POST requests. But it is possible, and it's trivial to combat, so give it a shot. This can also be diagnosed, if you use Chrome, by hitting f12, going to the "network" tab, and then running your form. It should tell you if the result was retrieved from cache.
Beyond that, if you're relying on magic_quotes (or worse, you're not relying on magic_quotes), you need to learn the proper way to deal with SQL injection. You should never be inserting untrusted data from the browser directly into the database. Escape it or use parameterized queries. If you're experiencing an intermittent problem with your query, it's probably related to the content of your comment throwing the query off under certain circumstances, as mentioned above, most likely with the inclusion of an apostrophe in a contraction. Diagnose by submitting two forms back to back: trythis and then try'this. If the first one goes and the second one fails, you've likely found your answer. Properly escaping your input would solve this problem.
Ultimately, all of these suggestions have already been given above, but hopefully this provides a little context to help understand the whys and wherefores.
Edit: I see, now that I look closer, that you are in fact escaping your query with a method you haven't shared here. Assuming that's working correctly, then that shouldn't be a concern.
Try echoing out a valid response at the beginning of your script without even executing anything. If that always returns, then you at least know the script is being called successfully.
There could be a problem with your working variable in the event that the ajax call returns with an error. It would never, under those circumstances, set it back to false.
Your #1 ally is the "network" tab in Chrome Developer Tools or watching the response in the console tab in Firefox Firebug extension.
Edit 2:
$.post('/ajax/comment.process.php',$(this).serialize(),function(msg){
// post stuff, REMOVING the working variable set, cuz it won't be necessary here...
},'json').always(function() { working = false; });

Related

how to pass ajax return value php variable

i know this question is asked many times, but non of them having right solution. i am using ajax to get the response from PHP Page. After getting the response i want to use the value in PHP variable. Below code is getting result but i am confused with the usage of it.
below is my index.php
function getLocation() {
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
} else {
alert("Geolocation is not supported by this browser.");
}
}
function geoSuccess(position) {
var glat = position.coords.latitude;
var glng = position.coords.longitude;
//alert("lat:" + glat + " lng:" + glng);
geocoding(glat,glng);
}
function geoError() {
alert("Geocoder failed.");
}
function geocoding(glat,glng){
$.ajax({
type:'POST',
url:'geolocation.php',
data:'latitude='+glat+'&longitude='+glng,
success:function(result){
if(result){
$("#locationg").val(result);
$("#htmllocation").html(result);
}
}
});
}
geolocation.php
<?php
session_start();
if(!empty($_POST['latitude']) && !empty($_POST['longitude'])){
//Send request and receive json data by latitude and longitude
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.trim($_POST['latitude']).','.trim($_POST['longitude']).'&sensor=false';
$json = #file_get_contents($url);
$data = json_decode($json);
$status = $data->status;
if($status=="OK"){
//Get address from json data
$location = $data->results[0]->formatted_address;
//$location = $data->results[0]->address_components;
for($j=0;$j<count($data->results[0]->address_components);$j++){
$cn=array($data->results[0]->address_components[$j]->types[0]);
if(in_array("locality", $cn))
{
$city= $data->results[0]->address_components[$j]->long_name;
}
}
}else{
echo 'No Location';
}
echo $city;
}
?>
index.php
<?php
$city='<span id="htmllocation"></span>';
?>
when i echo $city i am getting city name but in inspect elements its showing like
<span id="htmllocation">Visakhapatnam</span>
issue is that i can not use this in MYSQL because it in html format, and i just want to get only the city name nothing else.
i hope my issue is clear, please leave a comment if not clear.
The user locates example.com/index.php, it displays a webpage.
You get the user's location from JS.
You send it back to the server, and get the addresses of that location.
Then you want to access the addresses from index.php
Is that correct? If so, you can't do it. Things not work like that. Webservers uses request-response modells. When your php finishes, the server kills the process, ei. $city and everything else are destroied. After it, you get the user's location. If you want something from the server again, you must send a new request, because index.php's process is no longer available. This is impossible to get the city's name before you get it from the client, and you can't get the location from the client at the moment he first requests index.php, neither you can access an already-non-running process.
All you need to do is run your SQL query inside geolocation.php. When you get the result from Google, then fetch the data from your database. There $city doesn't contain any HTML codes, only the plain city name. Then send back some data related to that city to the user, and display it.
initially start session in PHP using
sessionstart()
method. then add this code after above code.
First set session using Jquery as below:
$.session.set("yoursessioname", "storevalue");
then try to get this session variable in PHP as below:
$city = $_SESSION['yoursessioname'];
I haven't tried it yet. I Hope it helps. :)
Use PHP in built function strip_tags to remove HTML tags from your statement to get only City in variable like below:
$city = strip_tags('<span id="htmllocation">Visakhapatnam</span>');
// Output will be Visakhapatnam only

POST Ajax data to public PHP function

NOTE - This is a edited snippet. This is testing at the moment and will be improved after.
I'm aiming to learn oop PHP now I got a good understanding of procedural. I'm stuck on sending this Ajax request to my php file.
Html File
<script>
$("#Question").click(function() {
flag = 1;
uid = "<?php echo $uid ?>";
var dataQuestion = {
uid,
flag,
ImageOne: $("#Image1").val()
};
//Post with AJAX
$.ajax({
type: "POST",
url: "../View/class.user.php",
data: dataQuestion,
perform: "QuestionsFunctions",
success: function(Returned){
$(".NotBoxSmall").text("Updated");
$(".NotBox").text("Updated");
flag = 0;
console.log(Returned);
},
error: function(){
$('.NotBox').text("Issue With Site");
$('.NotBoxSmall').text("Issue With Site");
}
});
});
</script>
Php file
<?php
public function QAsk(){
if($_POST['flag'] == 1){
$Image1 = $_POST['ImageOne'];
$uid = $_POST['uid'];
$insertsqlQ = "UPDATE UsersData
SET Image1 = '$Image1'
WHERE uid = $uid";
$resultquestion = mysqli_query($this->db,$insertsqlQ) or die(mysqli_connect_errno().json_encode("Data cannot inserted"));
return $resultquestion;
echo json_encode("Question Updated");
}else{
echo json_encode("Question NOPE");
return false;
}
}
?>
The id sends and iv'e tested this not within the public function and it appears to be fine. The request send back is blank, outside of the function it's the error log.
The issue is it says questions have been updated but no data has been added to the database.
jQuery must be initialized after the DOM ( document object model ).
How should I initialize jQuery?
I'd suggest some tips:
1 - Make the id names lower case #name_of_element
2 - Grab a OO PHP book and try to practice just this, run tests using curl for instance and make your database rules work before going into the client (html, js, css)
3 - Grab a jQuery book and run tests with mock data just printing a array from PHP. At the beginning is easier study stuff separated.
4 - '$Image1' is a varchar rather than the variable $Image1. Remove the quotes

How can i change a SELECT query using AJAX call

I'm very new to php and SQL so i'm really sorry if this is very trivial.
My site has multiple divs with table names inside it. The HTML is of the form:<p class="listname">(table name)</p>
I am trying to write a function so that when a user clicks on a div, the function gets the text using innerHTML and the contents of that particular table are shown.
The jquery function i wrote is:
$(document).ready(function(){
$(".listname").click(function(){
var x=($(this).html()).toLowerCase(); //this assigns the text in the class listname to the variable x
console.log(x);
$.ajax({
url: 'http://localhost/fullcalendar/events.php',
data: {name:x},
type: "GET",
success: function(json) {
}
});
});
});
And my PHP code is:
<?php
include 'ChromePhp.php';
ChromePhp::log('php running');
$json = array();
if($_POST['name']!=null)//check if any value is passed else use default value
{
$table=$_GET['name'];
ChromePhp::log($table);
}
else
{
$table= 'event';
ChromePhp::log($table);
}
$requete = "SELECT * FROM `$table` ORDER BY id";
try {
$bdd = new PDO('mysql:host=localhost;dbname=fullcalendar', 'root', 'root');
} catch(Exception $e) {
exit('Unable to connect to database.');
}
// Execute the query
$resultat = $bdd->query($requete) or die(print_r($bdd->errorInfo()));
// sending the encoded result to success page
echo json_encode($resultat->fetchAll(PDO::FETCH_ASSOC));
?>
When i first load the website, the default value for $table is used in the query, and data is retrieved. However, when i try clicking on a div, the correct value is passed to php and assigned to $table (i checked in the console) but the data displayed is of the default table i.e 'event' table.
How can i fix this?
PS: all my tables are in the same database.
You're checking the POST data:
if($_POST['name']!=null)
But using GET data:
type: "GET"
So the $_POST array will always be empty and your if condition will always be false. You probably meant to check the GET data:
if($_GET['name']!=null)
Also of note are a couple of other problems in this code:
Your success callback is empty, so this AJAX call isn't going to actually do anything client-side. Whatever you want to do with the returned data needs to be done in that success function.
This code is wide open to SQL injection. It's... very unorthodox to dynamically use table names like that. And this is probably an indication that the design is wrong. But if you must get schema object names from user input then you should at least be taking a white-list approach to validate that the user input is exactly one of the expected values. Never blindly execute user input as code.

Using Ajax to story response variable for php login

Ok so, some context. My college started doing some "learning on the job" type classes, and it's becoming a pain because it's like an internship without any sort of capacitation. Just my luck I was assigned a project I'm barely prepared for.
Right now I've been asked to join together an old Jamit Job Board with the login system of the place. Basically verify first if the user exist in the test database, then check if they exist in the local jobboard database. The problem is I don't have any ajax experience since it's not a topic we have touched in my classes. Sad, I know.
I was trying using cURL but was told by the supervisor it wouldn't work.
public function validar_request($Username,$Password) {
$Username = ($_REQUEST['username']);
$Password = md5(stripslashes($_REQUEST['password']));
function httpGet($url,p){
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
$respuesta1 = httpGet("http://www01pruebasweb.fod.ac.cr/upe/templates/interfaces/ConexionFramework.php?procedimiento=nombreUsuarioExiste&username=".$Username);
The URL will return a 1 is the user exists in the testing database, 0 if not. I was thinking on doing a series of If else that if response = 1, then proceed to login, else donĀ“t since its like a 3 step verification process. First if the user exists, then if the password exists, and lastly if both tables in both databases match.
Response I get in the browser looks like this.
If the user usuario_01 exists then I should get a one. The idea me and a teammate had was to use curl to store the 1 into a variable in php and compare it but it's not working. Specially with the mess that is, for me, the other code for logging of Jamit. I mainly have experience with Java, not web development so as you can understand I'm very overwelmed.
I was trying to contact support from Jamit to see if they had any help, but they aren't active since 2013. Though not sure how much help they would be.
Not sure if necessary but part of the code for logging of Jamit is this
function validate_candidate_login($login_page='') {
global $login_output;
if ($login_output) { echo $login_output; return; } // this function was buffered
if ($login_page=='') {
$login_page = JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."index.php";
}
global $label;
$Username = ($_REQUEST['username']);
$Password = md5(stripslashes($_REQUEST['password']));
$sql = "Select * From users Where Username='".jb_escape_sql($Username)."'";
$result = JB_mysql_query($sql);
// init $row
if (mysql_num_rows($result)==0) {
$row = array();
} else {
$row = mysql_fetch_array($result, MYSQL_ASSOC);
}
JBPLUG_do_callback('val_can_set_pass', $Password); // Note for Plugin authors: Password is passed by refrence. Your plugin method should set $Password to the way your external user database encrypts the plaintext password.. eg $Password = md5($_REQUEST['password']); for phpBB
JBPLUG_do_callback('val_can_login', $row); // Note for Plugin authors: $row argument is passed by reference, which is the row of your users table. The row is populated if username/pass are valid, $row['Username'] and $row['Password'] are set for the code below and should come from your external database. You may also set $row['Validated'] too
if ((!$row['Username']) && ($_REQUEST['silent']=='')) {
$label["c_login_invalid_msg"] = str_replace('%LOGIN_PAGE%', $login_page, $label["c_login_invalid_msg"]);
$label["c_login_invalid_msg"] = str_replace('%FORGOT_PAGE%',JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."forgot.php",$label["c_login_invalid_msg"]);
$label["c_login_invalid_msg"] = str_replace('%SIGNUP_PAGE%',JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."signup.php",$label["c_login_invalid_msg"]);
echo '<p style="text-align:center; ">'.$label["c_login_invalid_msg"]."</p>";
} else {
if ($row['Validated']=="0") {
$label["c_login_notvalidated"] = str_replace('%BASE_HTTP_PATH%', JB_BASE_HTTP_PATH, $label["c_login_notvalidated"]);
echo '<p style="text-align:center; ">'.$label["c_login_notvalidated"].'</p>';
} else {
if (($Password === $row['Password']) || ((JB_ALLOW_ADMIN_LOGIN=='YES')&&(JB_ADMIN_PASSWORD===$_REQUEST['password']))) {
JBPLUG_do_callback('val_can_login_sync', $row); // Note for Plugin authors: Initialize $row with a Jamit user row. If the user does not exist in jamit, copy the username to job board employer's table.
JBPLUG_do_callback('val_can_login_set_session', $row); // Note for Plugin authors: set session variables for your external database (successful login)
JB_set_candidate_session($row); // set session for the candidate
$label['c_login_welcome'] = str_replace ("%FNAME%", JB_escape_html($_SESSION['JB_FirstName']), ($label['c_login_welcome']));
$label['c_login_welcome'] = str_replace ("%LNAME%", JB_escape_html($_SESSION['JB_LastName']), ($label['c_login_welcome']));
$label['c_login_welcome'] = str_replace ("%USERNAME%", JB_escape_html($_SESSION['JB_Username']), ($label['c_login_welcome']));
if (isset($_REQUEST['page'])) {
$label['c_login_welcome'] = preg_replace('/index\.php/i', htmlentities($_REQUEST['page']), $label['c_login_welcome']);
}
if ($_REQUEST['silent']=='') {
echo '<p style="text-align:center; ">'.$label["c_login_welcome"].'</p>';
}
} else {
$label["c_login_invalid_msg"] = str_replace('%LOGIN_PAGE%', htmlentities($login_page), $label["c_login_invalid_msg"]);
$label["c_login_invalid_msg"] = str_replace('%FORGOT_PAGE%',JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."forgot.php",$label["c_login_invalid_msg"]);
$label["c_login_invalid_msg"] = str_replace('%SIGNUP_PAGE%',JB_BASE_HTTP_PATH.JB_CANDIDATE_FOLDER."signup.php",$label["c_login_invalid_msg"]);
if (strpos($login_page, 'apply_iframe.php')!==false) {
$label["c_login_invalid_msg"] = str_replace('_parent', '_self', $label["c_login_invalid_msg"]);
}
echo '<div style="text-align:center;">'.$label["c_login_invalid_msg"].'</div>';
}
}
}
}
Ok cool - per the comments you're looking to get started with AJAX (Asynchronous Javascript And XML). I would highly recommend linking jQuery to your html page to get started - it will make AJAX calls MUCH easier.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
Awesome, now we have jQuery loaded, which allows you to make an ajax call with a simple function.
So now we need to get values from the browser to the server. How do we do that? There are 2 approaches I would recommend:
1 - Use JSON (Javascript Object Notation) to send data to the server with key/value pairs. PHP is great for working with JSON.
2 - Serialize a form using jQueries $(formElement).serialize() function. This turns forms into key/value pairs and you can then receive the data using PHPs $_POST['keyOfFormField']
So I'm going to assume you're going with the JSON approach, which is always preferable in my opinion.
If you're unfamiliar with javascript, JSON format looks like this:
var jsonExample = {'Im a key': 'and im its value'};
This is how you represent an object literal in javascript, and we can send these to the server and store them in an associative array in PHP.
So, on to the ajax call. I will leave it up to you to research ways of getting your data into JSON format. It should be really simple.
In jQuery, an AJAX call looks like this:
$.ajax({
url: 'urlOfServerFile.php',
async: true,
data: JSON.stringify({'Im a key': 'Im its value'}),
type: "POST",
datatype: 'json',
success: function (json) {
json = JSON.parse(json);
//The server sent you back some data, do something with it!
},
error: function () {
alert("Please check your internet connection and try again");
}
});
So what is this doing?
$.ajax() is a function. In jQuery, you basically get access to this really awesome object, which is the jQuery object (it's also represented by the $ sign). So, $.ajax() is the same thing as saying jQuery.ajax()
The $.ajax() function takes an object as an argument. Remember that the {} is how we encapsulate an object in javascript.
The documentation for this object can be found here: http://api.jquery.com/jquery.ajax/
Basically, we need to tell the $.ajax() function a few things:
url - where are we sending this request?
async - will this request be sent asynchronously?
data - what data are we sending to the server?
type - what type of HTTP request are we sending this data in (POST, PUT, GET, etc)
datatype - what type of data are we sending?
success - what do we do if the request is successful?
error - what do we do if the request fails?
Well, at this point we've successfully sent data from browser to server asynchronously. How do we handle this in PHP? Here's how:
$input = json_decode(file_get_contents('php://input'), true);
This variable, $input is now an associative array with all of the JSON key/value pairs that we sent over. So, now we can store some of those values in variables like this:
$randomVariable = $input['im a key'];
I hope this post will get you started with AJAX. Once you get the hang of it, it's a really intuitive technology that will make your applications WAY better.

Jquery ajax call from javascript to PHP

There seems to be a problem with the code I have for calling php from javascript with jquery ajax. The ajax call seems to be successful but I don't get the correct information returned from the php function.
In the php function I create a SQL query. I send back the query as a reponse to debug it before performing a delete query. Here is the HTML for the div to show the query.
<div id="thenode" style="position: absolute; top: 30px; left: 0px; width: 150px; background-color: white; z-index: 9999;"> </div>
Here is the jquery ajax call. There are two variables being sent to the PHP function: nodeid for node to be delete, and option delete for the function.
function deleteitem()
{
//get selected node
var selectnod = getCookie('pnodid');
//define php info and make ajax call
$.ajax({
url: "uptree.php",
type: "POST",
data: { node: selectnod, option: "delete" },
cache: false,
success: function (response) {
$('#thenode').html(response);
}
});
}
Here is the PHP function.
<?php
function uptree() {
$node = $_POST['node'];
$option = $_POST['option'];
if($node == '' || $option == '') {
return '';
}
$dbco = mysql_connect('localhost', 'root', 'mmowebdb');
if (!$dbco)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("pagelinks", $dbco);
$sql = "DELETE FROM dtree_table WHERE nid='$node'";
return $sql;
}
?>
Should be straightforward but this ajax call returns an empty string and causes the div in the HTML to disappear. This is the first time I use ajax in an actual project. The problem must be easy to find for someone who knows what ajax really does. Can you tell the problems?
I found the answer! Thanks to all of you who had suggestions about the SQL call. But here is the actual answer to my question.
There are four steps in making an ajax Javascript to PHP call. The first two steps happen in the Javascript. The other two steps happen in the PHP.
Step 1. In Javascript decide what variables are needed in the PHP function, retrieve them.
Step 2. Make the ajax call to the PHP function. jquery has a convenient way of passing values to PHP. You have a an array of name-value pairs like this in the data item for the ajax call.
data: { node: selectnod, option: "delete" },
Step 3. Have your PHP function ready in a PHP file. Write the function like this.
function updatetree($node, $option) {
Step 4. Echo a call to the php function within that PHP file.
With these four steps you should have a succesful call to PHP and be able to return information to javascript from the PHP function.
Here is the javascript function.
function deleteitem()
{
//Get selected node to send to PHP function
var selectnod = getCookie('pnodid');
//Define php info, specify name of PHP file NOT PHP function
//Note that by loading the PHP file you will probably execute any code in that file
//that does not require a function call
//Send PHP variables in the data item, and make ajax call
//On success perform any action that you want, such as load a div here called thenode
$.ajax({
url: "uptree.php",
type: "POST",
data: { node: selectnod, option: "delete" },
cache: false,
success: function (response) {
$('#thenode').html(response);
}
});
}
Here is the PHP file uptree.PHP. It has a function defined, called updatetree. It also has an echo statement to call that function. This just seems to be the way to cause the function to run. Ajax itself doesn't call the function.
<?php
//Function defined here
//The variables will come from the ajax data statement
function updatetree($node, $option) {
if($node == '' || $option == '') {
return 'Select an item in the tree.';
}
$dbco = mysql_connect('localhost', 'root', 'mmowebdb');
if (!$dbco)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("pagelinks", $dbco);
$sql = '';
switch($option) {
case 'delete':
$sql = "DELETE FROM dtree_table WHERE nid='$node'";
break;
case 'add':
list($pagename, $address) = explode(",", $page);
$pagename = trim($pagename);
$address = trim($address);
$sql = "INSERT INTO dtree_table (nid, pid, name, url) values (NULL, ".$node.", '".$pagename."', '".$address."')";
break;
case 'update':
break;
}
if (!empty($sql)) return $sql;
}
//echo statement to run function, variables sent by ajax are retrieved with $_REQUEST
//they could have also been retrieved with $_GET or $_POST
echo updatetree(trim($_REQUEST['node']),trim($_REQUEST['option']),trim($_REQUEST['page']));
?>
So to recap. Javascript gets variables, makes ajax call to PHP file. Ajax loads PHP file which contains echo statement that causes PHP function to run. That PHP function is defined in that same file. The function return statement sends information back to javascript through ajax. Javascript does something with that information, e.g. load it into a div on the HTML page.
You actually need to execute the query you create:
$sql = "DELETE FROM dtree_table WHERE nid='$node'";
$result = mysql_query($sql);
return $sql;
Then result will contain a Boolean of success status.
Also when you pass it back to the javascript call you may need to set the appropriate page header of plaintext or json (if you decide to use json)
I highly recommend using a tool like Firebug to watch each ajax request. Then you can see the posted data, response data, and headers to help you diagnose your issue further. Currently only Firefox (AFAIK) fully supports the firebug extension, but firebug lite is also available for other browsers.
You haven't passed $sql into mysql_query();
$sql = "DELETE FROM dtree_table WHERE nid='$node'";
mysql_query($sql);
// -------^^^^^^^^
return $sql;
Your code is vulnerable to SQL injection, as it only checks for an empty $node. As an end user, I could delete any id in the database I wish, or all of them if I ran the code in a loop. You will need something to check that the user running the code has permission to delete the node, and also, call mysql_real_escape_string() on $node.
$node = mysql_real_escape_string($node);
$sql = "DELETE FROM dtree_table WHERE nid='$node'";
$result = mysql_query($sql);
// Check for success...
if ($result) {
// return success codes to ajax caller
}
else {
// return error codes to ajax caller
}
ADDENDUM
We don't see the code where you call upTree() in PHP. Are you actually calling the function? If you don't call it and that's your whole PHP script, then it will execute, do nothing, and return a blank HTTP response to your Ajax calling function with a successful 200 response code.
I send back the query as a reponse to debug it before performing a
delete query.
...
this ajax call returns an empty string and causes the div in the HTML
to disappear.
I assume you want the query displayed inside your div. You need echo($sql); or echo(uptree()); or equivalent somewhere in your program. You might also create an HTML form that POSTs the same data as your AJAX to see what PHP is returning.

Categories