phpjqueryajaxzend-frameworkzend-rest

Ajax reads success as error from zend rest controller


I'm using ajax to do a POST request to an API built on the Zend Framework. The API is returning a success JSON message, but AJAX is reading it as an error.

I've read through about a half dozen posts and implement their solutions. Nothing is helping.

My Zend Controller from the API

class LeadController extends Zend_Rest_Controller
{
    public function init()
    {
        $this->_helper->viewRenderer->setNoRender(true);
    }

    public function postAction()
    {
        $this->getResponse()
            ->setHttpResponseCode(201)
            ->setHeader('Cache-Control','no-cache', true)
            ->setHeader('Content-Type', 'application/json', TRUE)
            ->setHeader('charset', 'utf-8', TRUE)
            ->appendBody(json_encode(array('results' => 'success')));
            return;
    }
}

I'm using Charles to verify that the Response code and content types are being set correctly.

Here's my JSON response, which I've validated.

    {"results":"success"}

My AJAX code

$.ajax({
    type: 'POST',
    url: myurl,
    data: inputs,
    cache: 'false',
    success: function(data){
        console.log('success');
    },
    error: function(xhr, status, thrown){
        console.log("Error:");
        console.log(status);
    }
});

The success function never gets called. It's always the error function. What am I doing wrong?

UPDATE

I tried it out in Chrome and got an xmlhttprequest cannot load access-control-allow-origin error message. After some investigation I found that you can't use AJAX to access a URL on a different domain. I created a PHP script on the same domain as the Javascript that calls the API via curl. I've set my ajax script up to use the go-between script and it's working just fine.

I just changed the url line in the ajax function to get it working

url: 'localscript.php',

Here's the localscript.php file that is calling the Zend Rest API in case anyone finds it useful.

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

//add fields from POST
foreach($_POST as $key => $value) {
        $data[$key] = $value;
}

//url-ify the data for the POST
$fields_string ='';
foreach($data as $key=>$value) {
     $fields_string .= $key.'='.urlencode($value).'&'; 
}

rtrim($fields_string,'&');

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)');

//execute post
$result = curl_exec($ch);
$info = curl_getinfo($ch);

$start = stripos($result, "<body");
$end = stripos($result, "</body");

$body = substr($result,$start,$end);
echo $body;

//close connection
curl_close($ch); 

}


Solution

  • I think you have to add dataType:'jsonp' parameter for the $.ajax function. Read more about dataType

    Additionally, Zend has Zend_Controller_Action_Helper_Json which removes layout and sends correct Content-Type.

    Example:

    public function deleteAction()
    {
            $this->_helper->json(array(
                'msg'     => 'Lead has been deleted.',
                'success' => true));
    }