Post return values with AJAX? - javascript

I am using Code Igniter and I have the following Javascript function in my View. I have tried to echo values such as "error" from my handler function in the controller, but the "success" code is always ran in this function below instead.
Do I use echo or return to respond to the AJAX post? What value do I return for success and failure?
<script>
function removeDatacenter(id)
{
var cfm = confirm("Do you wish to delete this datacenter?");
if (cfm==true)
{
$.ajax({
type: "POST",
url: "<?=base_url()?>datacenters/remove_handler.php",
data: { id: id },
success: function(result)
{
document.location.href = document.URL + "?result=success";
},
error: function(result)
{
document.location.href = document.URL + "?result=failed";
}}
);
}
};
</script>

The success-method runs if the ajax-request was successfully sent to your script. It does not say anything about what the request returned.
If you simply do echo "error"; in your PHP-script, you can check the value in the success-method like this:
success: function(response) {
if (response == "error") {
document.location.href = document.URL + "?result=failed";
}
else {
document.location.href = document.URL + "?result=success";
}
}
Edit: People tend to use json_encode in the PHP-code and decode the json-string to an object in the javascript-code. That way you can send more structured data from your script.

Any text you echo will be seen, by AJAX, as a success. Even if it's the word "error". In order for you to trigger the Javascript error handler, you need to trigger some sort of actual HTTP error. If you're just trying to trigger an error for testing purposes, you could throw an exception in your controller. Or point the AJAX request to a URL that doesn't exist on your server (then you'd get a 404 error).
By the way, the error callback you have in your Javascript is slightly off on the API. It might not matter depending on what you do in the error handler, but here's the full call:
error: function(xmlHttpRequest, textStatus, errorThrown) {
//handle error here
}

Related

Pass string from php to js function

Unable to pass a string from a php page to another page's js function.
It is to display message after checked the adding item is existing in an array or not. I've tried either adding quotes or not in the alert statement
1. with quotes in alert statement, javascript didn't convert the statement but just display it directly.
2. without quotes in alert statement, Chrome says it's an error if without quotes.
add_product.php (js function):
function add_to_cart(){
jQuery('#modal_errors').html("");
var error='';
var available =$("#size option:selected").data("available");
var quantity = jQuery('#quantityInput').val();
{document.getElementById("available").value = available;
var data = jQuery('#add_product_form').serialize();
jQuery.ajax({
url : 'cart.php',
method : 'post',
data : data,
success: function(){
alert("<?php echo $respMsg; ?>");
location.reload();},
error : function(){alert("something wrong");}
});
return;
}
cart.php:
if ($duplicate==false){
$respMsg="The item is in cart now.";
} else {
$respMsg="You have added the item twice.";
}
I expect a js msgbox popup to show either one of the php messages, but the actual output is either telling syntax error or displays the code string.
If you want to print your response, then you can't say alert("<?php echo $respMsg; ?>");
What you have to do is actually get the data in the callback and alert that data.
success: function(data){
alert(data);
location.reload();
},
First, you need to use a function into cart.php returning the $respMsg result, then use data response from de jQuery.ajax function to alert the message:
jQuery.ajax({
url : 'cart.php',
method : 'post',
data : data,
success: function(data){
alert("Message: " + data);
location.reload();
},
error : function(){
alert("something wrong");
}
});
More information about data response and success response, into jQuery manual
EDIT:
Also you need to delete the curly brace here:
{document.getElementById("available").value = available;
It may cause JS syntax error.

Unable to get response from php return in ajax request

I am trying to access the output from php code to jquery ajax. But I donot know why It is returning me whole page html including the result. can anybody please tell me about it. In firefox console Its show me response of page html including php result. But In jquery code console.log does not hit.
Here is jquery code
function getprofile()
{
$.ajax({
url: 'Userpage/get_profile',
//data: {'title': title}, change this to send js object
type: "post",
dataType: 'json',
data: {'userid': 1},
success: function(data) {
console.log(data);
}
});
}
My php code
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Userpage extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->helper('url');
$this->load->helper('form');
$this->load->library("session");
$this->load->model("Userpage_model");
$this->load->view('Userpage_view');
}
public function index()
{
}
public function get_profile()
{
$data = array();
$post_id = $this->input->post('userid');
$data['comments'] = $this->Userpage_model->get_profile($post_id);
echo json_encode($data['comments']);
exit;
}
}
?>
Please review the code and tell me where I am going wrong
Thanks
Use exit
public function get_profile()
{
$data = array();
$post_id = $this->input->post('userid');
$data['comments'] = $this->Userpage_model->get_profile($post_id);
echo json_encode($data['comments']);
exit; // use exit here
}
EDIT
PHP uses a special function called header() for setting properties of the page during rendering.
you need to return from your function, using exit is fine but it's not a good practice
public function get_profile()
{
$data = array();
$post_id = $this->input->post('userid');
$data['comments'] = $this->Userpage_model->get_profile($post_id);
return json_encode($data['comments']);
}
You are using CI. From this ajax call:
$.ajax({
url: 'Userpage/get_profile',
success: function(data) {
console.log(data);
}
});
you expect an ajax call is being made to get_profile action inside Userpage controller, that probably will return:
{
"comments": [
{ ... },
{ ... },
{ ... },
...
]
}
which will be logged in browser console.
But you get unexpected result, right?
I think, your ajax call results in error. To prove this, modify your ajax call:
$.ajax({
url: 'Userpage/get_profile',
success: function(data) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
// add this function to logs error
console.log(textStatus + ': ' + errorThrown);
}
});
Now, if the ajax call results in error, you can see the error in browser console. I am pretty sure you will get error: Not Found in browser console.
You are using CI, the URL will be something like:
http://<something>/index.php/site/index
In this page, if you make ajax call with url Userpage/get_profile, what the browser really does is make ajax call to:
http://<something>/index.php/site/index/Userpage/get_profile
instead of what you expect:
http://<something>/index.php/Userpage/get_profile
To solve this, you must change the value of url in your ajax call, to point the correct URL above.
By using CI, the absoulte URL above can be generated with the help of site_url() function:
site_url('Userpage/get_profile')
I usually print this URL somewhere in HTML, and retrieve it from javascript during ajax call.

JQuery If Else statement never executed

I'm using a simple if else statement to check for response from a POST form.
This is weird: I can check for response in form of error. Using elseif: or else: just does absolut nothing. Even though the response is valid.
Current code:
post_data = {
'someData': someData
}
// Ajax post data to server
$.post('register.php', post_data, function(response) {
if (response.type == 'error') {
if (response.errorType == 'something') {
$("#someThing").addClass('has-error');
}
} else {
window.location.reload(true);
}
}, 'json');
This is so weird. I've tried to insert alerts to really check if the else statement ran in background or something.
When the response is: "error" the error statement is executed.
However when the response is: success/done/cleared/failed etc. (whatever i try) nothing happens.
I receive the respond in console - but JQuery doesnt run the } else { ... statement.
Actually its not what you think.
The function is only called on Success. For error handling you have to chain another function
For example try this:
post_data = {
'someData':someData
}
// Ajax post data to server
$.post('register.php', post_data).done(function (response) {
// This is your success function
window.location.reload(true);
})
.fail(function (xhr, textStatus, errorThrown) {
console.log("Post error: " + errorThrown);
$("#someThing").addClass('has-error');
});
I hope this help you to understand that weird behavior :P
jQuery documentation have different handling functions for different jQuery version. so better to use $.ajax

Making Ajax call from javascript

I have the following jquery ajax call and it works fine in a purely jquery file.
var request = $.ajax({
url: "kscript.jsp",
type: "POST",
data: {st:start, sp:stop},
dataType: "html"
});
request.done(function(msg) {
$("#output").html( msg );
alert("Success!!!"+msg);
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
Thereafter I rewrote my code as a javascript, but I am now putting the ajax call directly inside a javascript function. This hasn't worked and I am getting 500 Internal Server Error.
function myAjax(){
var request = $.ajax({
url: "kscript.jsp",
type: "POST",
data: {st:start, sp:stop},
dataType: "html"
});
request.done(function(msg) {
$("#output").html( msg );
alert("Success!!!"+msg);
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
}
I have also tried this:
function ajaxFunction() {
xmlhttp.open("POST","kscript.jsp",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("st=start&sp=stop");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("output").innerHTML=xmlhttp.responseText;
}
}
}
but the same error: 500 Internal Server Error. In all these instances, the error is pointing to kscript.jsp .I have ensured that the URL and spelling is correct but hasn't worked. I would appreciate your suggestion to fix this problem.
here is kscript.jsp
<%
String astart = request.getParameter("start");
String sptimes=request.getParameter("stop");
out.print("<h1> Start is: "+start+" -- Stop is"+stop +"</h1>");
%>
it's looks like a folders structure problem, you shoudl ensure that the relative path is fine, I mean, if you are calling from a js you should point to /jsp/yourJsp.jsp , checkit... by the way, are you using the F12 tools to validate the response from the server ?
i think you are making some mistake to call java script method.so check or have you describe ajaxcall inside javascript tag.
You are trying to access the wrong parameters in jsp.
The error occurs here:
String astart = request.getParameter("start");
the parameters are st and sp, not start and stop.
you need:
String astart = request.getParameter("st");
String sptimes=request.getParameter("sp");
Or, you can change the js to pass the correct parameters:
data: {start:start, stop:stop},

Codeigniter ajax CSRF problem

I've made a simple autoload function that loads content when you scroll down on a website. However, there seems to be a few problems when i enable CSRF protection in Codeigniter.
I'm not using a form, so i don't know how i can send the token from A to B when i'm doing my post request as you scroll.
My JavaScript
if (location.href == baseurl) {
$(window).scroll(function(){
if ($(window).scrollTop() > $('body').height() / 2) {
if(doScroll == 1) {
$.post(baseurl + 'ajax/images',{'id' : ID}, function(data) {
$("#wrapper_content").append(data);
if(data == 'Det finnes ikke flere bilder i databasen, WTF!? Send inn forslag ASAP!') {
doScroll = 0;
}
ID++;
});
}
}
});
}
Since Codeigniter expects a TOKEN on all POST request i can't get this to work when CSRF i enabled. Any suggestions?
Error when CSRF is Enabled
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
If i turn CSRF off, everything works great...
You might like to try this code I've used. It works great:
<script type="text/javascript">
$(function(){
$('.answerlist').each(function(e){
$(this).click(function(){
var valrad = $("input[#name=answer]:checked").val();
var post_data = {
'ansid': valrad,
'<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>'
};
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>online/checkanswer",
data: post_data,
success: function(msg){
/// do something
}
});
});
});
});
</script>
As others say - you have to post the CSFR token name and its value with the AJAX request parameters. Here is a simple solution to append it automatically to every AJAX request.
Here is what I put on my main view, so this code is on every page before loading the other javascript files:
<script>
var csfrData = {};
csfrData['<?php echo $this->security->get_csrf_token_name(); ?>']
= '<?php echo $this->security->get_csrf_hash(); ?>';
</script>
<!-- ... include other javascript files -->
</body>
</html>
And here is a part of a javascript file that I include on every page:
$(function() {
// Attach csfr data token
$.ajaxSetup({
data: csfrData
});
});
If you want, you can echo both the token name and the hash somewhere appropriate. Something like this.
echo $this->security->get_csrf_token_name()
and
echo $this->security->get_csrf_hash()
Or, you could use form_open() as usual and use the hidden input that is generated for you from your javascript. Disabling the CSRF-functionality is the wrong way to go.
Having reviewed my situation I believe the best option is to use CSRF but reset the token on each attempt. Otherwise the ideas expressed earlier about re-using the cookie token would allow an attacker to resubmit data hundreds of times using the same token which defeats the object of the point.
As such I have created the following function:
public function resetCSRF(){
$this->security = null;
$_COOKIE[$this->config->item('csrf_cookie_name')] = null;
load_class('Security', 'core');
$this->security->csrf_set_cookie();
return $this->security->get_csrf_hash();
}
If for example an ajax based login form fails - call this function in your PHP and then on the javascript side that receives the failure (this solution uses Jquery and a getCookie function from w3schools) would then simply call:
$('input[name="csrf_test_name"]').val(getCookie('csrf_cookie_name'));
Basically what you need to do is get the expected csrf value from the cookie (named 'ci_csrf_token' by default), then post it along with your other data.
You would need to modify this line:
$.post(baseurl + 'ajax/images',{'id' : ID}, function(data) {
to:
$.post(baseurl + 'ajax/images',{'id' : ID,'ci_csrf_token' : $.cookie('ci_csrf_token')}, function(data) {
Might need to install the cookie addon (I'm not really sure; I use mootools). Here is more information: http://aymsystems.com/ajax-csrf-protection-codeigniter-20.
Previous suggestions work great, but rather than using a variable that you can apply in every data-post, I find it simpler to use the ajax-setting to automatically apply this token to every post:
$(document).ajaxSend(function(elm, xhr, s){
if(s.data){
s.data += '&';
}
s.data += '<?php echo $this->security->get_csrf_token_name(); ?>=<?php echo $this->security->get_csrf_hash(); ?>';
});
(works with jquery-1.9.1. I'm not sure about other jquery-versions)
The only problem with a few of the above answers is that a csrf token is only valid for one request, so if you make a post request via ajax and do not refresh the page you will not have the current csrf token for your next ajax post request. This is my solution:
In your CodeIgniter Controller:
$data = array('data'=> 'data to send back to browser');
$csrf = $this->security->get_csrf_hash();
$this->output
->set_content_type('application/json')
->set_output(json_encode(array('data' => $data, 'csrf' => $csrf)));
$data = the data to return to the browser
$csrf = new csrf token to be used by the browser for next ajax post request
Obviously you can output this in other ways but JSON is used mostly with ajax calls. Also include this token in every post response to be used for the next post request
Then in your next ajax request (javascript):
var token = data.csrf;
$.ajax({
url: '/next/ajax/request/url',
type: 'POST',
data: { new_data: 'new data to send via post', csrf_token:token },
cache: false,
success: function(data, textStatus, jqXHR) {
// Get new csrf token for next ajax post
var new_csrf_token = data.csrf
//Do something with data returned from post request
},
error: function(jqXHR, textStatus, errorThrown) {
// Handle errors here
console.log('ERRORS: ' + textStatus + ' - ' + errorThrown );
}
});
Also remember that where I've got csrf_token:token replace crf_token with the name of your token found in application/config/config.php on line that states $config['csrf_token_name'] = 'csrf_token';

Categories

Resources