CakePHP handles this correctly because JSON is the response type, not the request type. The terms of the request and response may lead to some confusion. The request object represents the header information of the HTTP request sent to the server. The browser usually sends POST or GET requests to the server, and these requests cannot be formatted as JSON. Therefore, the request cannot be of type JSON.
With that said, the server can give a JSON response, and the browser can put the request header so that it supports the JSON response. Therefore, instead of checking what the request is. Check which accepted answers are supported by the browser.
So instead of writing $this->request->isJson() you should write $this->request->accepts('application/json') .
This information is ambiguously shown in the document here , but see also links in the is(..) documentation are missing see also links. So many people look there first. You do not see JSON and assume that something is missing.
If you want to use the request detector to check if the browser supports JSON response, you can easily add one insert to your beforeFilter file.
$this->request->addDetector('json',array('callback'=>function($req){return $req->accepts('application/json');}));
There is a risk associated with this approach, as the browser may send several types of responses as a possible response from the server. Includes wildcard for all types. Thus, this limits you to only requests pointing to a JSON response. Since JSON is a text format, the text/plain type is a valid response type for a browser that expects JSON.
We could modify our rule to include text/plain for JSON responses like this.
$this->request->addDetector('json',array('callback'=>function($req){ return $req->accepts('application/json') || $req->accepts('text/plain'); }));
This will include text / simple requests as a JSON response type, but now we have a problem. Just because the browser supports a text / simple response does not mean that it expects a JSON response.
That's why it's better to include a naming convention in your URL to indicate a JSON response. You can use the .json file .json or the /json/controller/action prefix.
I prefer using a named prefix for URLs. This allows you to create json_action methods in your controller. You can then create a detector for this prefix.
$this->request->addDetector('json',array('callback'=>function($req){return isset($req->params['prefix']) && $req->params['prefix'] == 'json';}));
Now this detector will always work correctly, but I claim that it is a misuse of JSON request detection. Since there is no such thing as a JSON request. Only JSON responses.