if request has content-type as application/json, how does cakephp fit the payload into $this->request->data?

StackOverflow https://stackoverflow.com/questions/21215722

質問

I noticed that my angularjs needs to set headers as the following in order for it to work nicely with CakePHP.

angularApp.config(function ($httpProvider) {
  $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
  $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
  $httpProvider.defaults.headers.common['Accept'] = 'application/json';
  $httpProvider.defaults.transformRequest = function(data) {
      if (data === undefined) {
          return data;
      }
      return $.param(data);
  }
});

My CakePHP is 2.4 and uses JsonView to render ajax requests.

My question is that the angularjs default header for Content-Type is application/json;charset=utf-8 and if I use that as default and JSON.stringify my data,

can CakePHP work with that?

If not, what changes do I need to make to my code within CakePHP context?

役に立ちましたか?

解決

Reading this tells us that:

if your Content-Type is the usual application/x-www-form-urlencoded, then even if you send an ajax request, CakePHP will help you parse the payload into $this->request->data properly.

However, if Content-Type is application/json, then you need to use $this->request->input('json_decode')

Basically, we assume your angularjs config is:

angularApp.config(function ($httpProvider) {
  // because you did not explicitly state the Content-Type for POST, the default is application/json
  $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
  $httpProvider.defaults.headers.common['Accept'] = 'application/json';
  $httpProvider.defaults.transformRequest = function(data) {
      if (data === undefined) {
          return data;
      }
      //return $.param(data);
      return JSON.stringify(data);
  }
});

There is incomplete information there.

Assuming you are still taking in data and manipulate it as an array, you need to actually use $this->request->input('json_decode', true).

To help matters, save this as either a protected method on AppController or at the appropriate controller.

protected function _decipher_data() {
    $contentType = $this->request->header('Content-Type');
    $sendsJson = (strpos($contentType, 'json') !== false);
    $sendsUrlEncodedForm = (strpos($contentType, 'x-www-form-urlencoded') !== false);

    if ($sendsJson) {
        $this->request->useful_data = $this->request->input('json_decode', true);
    }
    if ($sendsUrlEncodedForm) {
        $this->request->useful_data = $this->request->data;
    }
    return $this->request->useful_data;
}

Then in the appropriate action, you can do

$data = $this->_decipher_data();
$data['User']['id'] = $id;

OR

inside your beforeFilter you do this:

$this->_decipher_data();

then in the appropriate action, you do this:

$this->request->useful_data['User']['id'] = $id
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top