Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POST data not appearing in CakePHP controller

I'm using AJAX on a knockout.js form to post some information that CakePHP should receive, however, Cake doesn't seem to find anything. Also, the alert isn't appearing despite a 200 status (OK) from the POST.

Here's the AJAX

$.ajax({  
          url: "/orders/finalize_payment",  
          type: "POST",  
          dataType: "json",  
          contentType: "json",  
          data: JSON.stringify({"customer": customer_id}),  
          success: function(){              
            alert("success");  
          }
    }); 

Here's the corresponding action in the orders controller. Right now, I completely stripped it to just the bare minimum.

function finalize_payment($id = null){
    $this->layout = false;
    $this->autoRender = false;
    if($this->request->is('post')){ //the user has submitted which status to view
        print_r($this->request->data);
            echo "test"; //just to make sure it's reaching this point
    }
}

When I open up the network tab in chrome, it shows the request payload as

customer: 1

The POST shows as success, status 200. I checked the response headers and it just shows

array
(
)
test

Despite chrome showing a payload being sent, CakePHP isn't finding it apparently.

Update

I changed the request from AJAX to $.post and it worked. I still have no clue why

$.post("/orders/finalize_payment",{"customer_id":customer_id},function(data){
        alert('success');
 });
like image 680
user1104854 Avatar asked Jul 18 '13 19:07

user1104854


1 Answers

Don't encode post data as json

The code in the question won't appear in any php script, the reason is this:

contentType: "json"

It's not a form-url-encoded request, so e.g. the following code:

print_r($_POST);
print_r(file_get_contents('php://input'));

will output:

Array()
'{"customer":123}'

If you want to submit data as json, you'll need to read the raw request body:

$data = json_decode(file_get_contents('php://input'));

There might be times when that's desirable (api usage), but that isn't the normal way to use $.post.

The normal way

The normal way to submit data, is to let jQuery take care of encoding things for you:

$.ajax({  
    url: "/orders/finalize_payment",  
    type: "POST",  
    dataType: "json",  // this is optional - indicates the expected response format
    data: {"customer": customer_id},  
    success: function(){              
       alert("success");  
    }
});

This will submit the post data as application/x-www-form-urlencoded and be available as $this->request->data in the controller.

Why $.post works

I changed the request from AJAX to $.post and it worked. I still have no clue why

Implicitly with the updated code in the question you have:

  • removed the JSON.stringify call
  • changed from submitting json to submitting application/x-www-form-urlencoded

As such, it's not that $.post works and $.ajax didn't ($.post infact just calls $.ajax) - it's that the parameters for the resultant $.ajax call are correct with the syntax in the question.

like image 139
AD7six Avatar answered Nov 03 '22 03:11

AD7six