Home » Php » php – Getting json on Ajax response callback

php – Getting json on Ajax response callback

Posted by: admin July 12, 2020 Leave a comment

Questions:

I am trying to create a little ajax chat system (just for the heck of it) and I am using prototype.js to handle the ajax part.

One thing I have read in the help is that if you return json data, the callback function will fill that json data in the second parameter.

So in my php file that gets called I have:

header('Content-type: application/json');

if (($response = $acs_ajch_sql->postmsg($acs_ajch_msg,$acs_ajch_username,$acs_ajch_channel,$acs_ajch_ts_client)) === true)
    echo json_encode(array('lastid' => $acs_ajch_sql->msgid));
else
    echo json_encode(array('error' => $response));

On the ajax request I have:

onSuccess: function (response,json) {
                alert(response.responseText);
                alert(json);    
            }

The alert of the response.responseText gives me {“lastid”: 8 } but the json gives me null.

Anyone know how I can make this work?

How to&Answers:

This is the correct syntax for retrieving JSON with Prototype

onSuccess: function(response){
   var json = response.responseText.evalJSON();
}

Answer:

There is a property of Response: Response.responseJSON which is filled with a JSON objects only if the backend returns Content-Type: application/json, i.e. if you do something like this in your backend code:

$this->output->set_content_type('application/json');
$this->output->set_output(json_encode($answer));
//this is within a Codeigniter controller

in this case Response.responseJSON != undefined which you can check on the receiving end, in your onSuccess(t) handler:

onSuccess:function(t) {
  if (t.responseJSON != undefined) 
  {
    // backend sent some JSON content (maybe with error messages?)
  }
  else 
  {
    // backend sent some text/html, let's say content for my target DIV
  }
}

I am not really answering the question about the second parameter of the handler, but if it does exist, for sure Prototype will only provide it in case of proper content type of the response.

Answer:

This comes from Prototype official :

Evaluating a JavaScript response
Sometimes the application is designed
to send JavaScript code as a response.
If the content type of the response
matches the MIME type of JavaScript
then this is true and Prototype will
automatically eval() returned code.
You don’t need to handle the response
explicitly if you don’t need to.

Alternatively, if the response holds a
X-JSON header, its content will be
parsed, saved as an object and sent to
the callbacks as the second argument:

new Ajax.Request(‘/some_url’, {
method:’get’, onSuccess:
function(transport, json){

  alert(json ? Object.inspect(json) : "no JSON object");

}   

});

Use this functionality when you want to fetch non-trivial
data with Ajax but want to avoid the
overhead of parsing XML responses.
JSON is much faster (and lighter) than
XML.

Answer:

You could also just skip the framework. Here’s a cross-browser compatible way to do ajax, used in a comments widget:

//fetches comments from the server
CommentWidget.prototype.getComments = function() {
  var commentURL = this.getCommentsURL + this.obj.type + '/' + this.obj.id; 
  this.asyncRequest('GET', commentURL, null);
}


//initiates an XHR request
CommentWidget.prototype.asyncRequest = function(method, uri, form) {
  var o = createXhrObject()
  if(!o) { return null; } 
  o.open(method, uri, true);
  o.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
  var self = this;
  o.onreadystatechange =  function () {self.callback(o)};
  if (form) { 
    o.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    o.send(makePostData(form)); 
  } else {
    o.send(''); 
  }  
}

//after a comment is posted, this rewrites the comments on the page
CommentWidget.prototype.callback = function(o) {                  
  if (o.readyState != 4) { return }
  //turns the JSON string into a JavaScript object.
  var response_obj = eval('(' + o.responseText + ')');
  this.comments = response_obj.comments;
  this.refresh()
}

I open-sourced this code here http://www.trailbehind.com/comment_widget