Cakephp3:如何返回json数据?
我正在对cakePhp控制器进行ajax post调用:Cakephp3:如何返回json数据?,json,cakephp,Json,Cakephp,我正在对cakePhp控制器进行ajax post调用: $.ajax({ type: "POST", url: 'locations/add', data: { abbreviation: $(jqInputs[0]).val(), description: $(jqInputs[1]).val()
$.ajax({
type: "POST",
url: 'locations/add',
data: {
abbreviation: $(jqInputs[0]).val(),
description: $(jqInputs[1]).val()
},
success: function (response) {
if(response.status === "success") {
// do something with response.message or whatever other data on success
console.log('success');
} else if(response.status === "error") {
// do something with response.message or whatever other data on error
console.log('error');
}
}
});
当我尝试此操作时,会收到以下错误消息:
控制器操作只能返回Cake\Network\Response或null
在AppController中,我有这个
$this->loadComponent('RequestHandler');
启用
控制器功能如下所示:
public function add()
{
$this->autoRender = false; // avoid to render view
$location = $this->Locations->newEntity();
if ($this->request->is('post')) {
$location = $this->Locations->patchEntity($location, $this->request->data);
if ($this->Locations->save($location)) {
//$this->Flash->success(__('The location has been saved.'));
//return $this->redirect(['action' => 'index']);
return json_encode(array('result' => 'success'));
} else {
//$this->Flash->error(__('The location could not be saved. Please, try again.'));
return json_encode(array('result' => 'error'));
}
}
$this->set(compact('location'));
$this->set('_serialize', ['location']);
}
我错过了什么?是否需要其他设置?不要返回json_编码结果,而是使用该结果设置响应正文并返回
public function add()
{
$this->autoRender = false; // avoid to render view
$location = $this->Locations->newEntity();
if ($this->request->is('post')) {
$location = $this->Locations->patchEntity($location, $this->request->data);
if ($this->Locations->save($location)) {
//$this->Flash->success(__('The location has been saved.'));
//return $this->redirect(['action' => 'index']);
$resultJ = json_encode(array('result' => 'success'));
$this->response->type('json');
$this->response->body($resultJ);
return $this->response;
} else {
//$this->Flash->error(__('The location could not be saved. Please, try again.'));
$resultJ = json_encode(array('result' => 'error', 'errors' => $location->errors()));
$this->response->type('json');
$this->response->body($resultJ);
return $this->response;
}
}
$this->set(compact('location'));
$this->set('_serialize', ['location']);
}
编辑(归功于@Warren Sergent)
由于CakePHP3.4,我们应该使用
return $this->response->withType("application/json")->withStringBody(json_encode($result));
而不是:
$this->response->type('json');
$this->response->body($resultJ);
return $this->response;
返回的东西很少
JSON
响应:
RequestHandler
组件json
\u序列化值
protected function setJsonResponse(){
$this->loadComponent('RequestHandler');
$this->RequestHandler->renderAs($this, 'json');
$this->response->type('application/json');
}
稍后在控制器中,您应该调用该方法,并设置所需的数据
if ($this->request->is('post')) {
$location = $this->Locations->patchEntity($location, $this->request->data);
$success = $this->Locations->save($location);
$result = [ 'result' => $success ? 'success' : 'error' ];
$this->setJsonResponse();
$this->set(['result' => $result, '_serialize' => 'result']);
}
另外,看起来您还应该检查request->is('ajax)
;我不确定在GET
请求的情况下是否返回json
,因此setJsonResponse
方法在if post
块中调用
在ajax调用成功处理程序中,您应该检查result
字段值:
success: function (response) {
if(response.result == "success") {
console.log('success');
}
else if(response.result === "error") {
console.log('error');
}
}
返回JSON数据时,需要定义数据类型和响应主体信息,如下所示:
$cardInformation = json_encode($cardData);
$this->response->type('json');
$this->response->body($cardInformation);
return $this->response;
在您的情况下,只需更改此返回json_encode(数组('result'=>'success')代码>带有以下代码的行:
$responseResult = json_encode(array('result' => 'success'));
$this->response->type('json');
$this->response->body($responseResult);
return $this->response;
发送json不需要RequestHandler。
在控制员的行动中:
$this->viewBuilder()->setClassName('Json');
$result = ['result' => $success ? 'success' : 'error'];
$this->set($result);
$this->set('_serialize', array_keys($result));
在最新版本的CakePHP中,$this->response->type()
和$this->response->body()
不推荐使用
相反,您应该使用$this->response->withType()
和$this->response->withStringBody()
例如:
(这是从公认的答案中删去的)
我在这里看到的大多数答案要么是过时的,充斥着不必要的信息,要么是依赖于withBody()
,这让人觉得是权宜之计,而不是死板的方法
以下是对我有效的方法:
$my_results = ['foo'=>'bar'];
$this->set([
'my_response' => $my_results,
'_serialize' => 'my_response',
]);
$this->RequestHandler->renderAs($this, 'json');
。似乎它不会很快被弃用
更新:CakePHP 4
$this->set(['my_response' => $my_results]);
$this->viewBuilder()->setOption('serialize', true);
$this->RequestHandler->renderAs($this, 'json');
从cakePHP 4.x.x开始,假设您的控制器和路由设置如下所示,则以下各项应起作用:
控制器:/src/controller/studentscocontroller.php
路由:/config/Routes.php
虽然我不是CakePHP大师,但我使用的是cake>4,我需要通过ajax调用获得一些结果。为此,我在控制器上写下
echo json_编码(Dashboard::recentDealers());死亡
在我的JS文件中,我只需要使用
JSON.parse(数据)
ajax调用类似于
$.get('/recent-dealers', function (data, status) {
console.log (JSON.parse(data)); });
});
控制器操作只能返回Cake\Network\Response或null。
此错误消息有什么不清楚的地方?显然,您返回了一个字符串return json\u encode()
。对不起,我还是不明白重点是什么?我返回一个数组,就像上面的例子一样?你没有。你读过这个吗?首先,不要返回json,只需回显它,以便在结果中打印它。第二,如果您没有将标题内容类型设置为json,那么您必须在ajax中提及它,如以下数据类型:'json'@AmanRawat No,您不会回显来自控制器操作的数据!您可以返回响应对象、在模板中回显数据,或者使用序列化视图;和$this->response->body($resultJ);帮了我很多,谢谢!我更新了anwser以包含验证错误。值得注意的是,由于CakePHP3.4,这不再有效。您应该改为使用return$this->response->withType(“application/json”)->withStringBody(json_encode($result))代码>允许将字符串传递给不可变响应。这是一个方便的答案!另外,my_response
可以是任何有效的键名,只需要在两个位置匹配即可。此外,这在CakePHP 3.6.10上起到了作用(我想我应该澄清一下),如果没有该组件,它将无法工作!所以这不是一个通用的解决方案。@MSS什么组件?RequestHandler组件被整理好了
public function index()
{
$students = $this->Students->find('all');
$this->set(compact('students'));
$this->viewBuilder()->setOption('serialize',['students']);
}
<?php
use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;
/** @var \Cake\Routing\RouteBuilder $routes */
$routes->setRouteClass(DashedRoute::class);
$routes->scope('/', function (RouteBuilder $builder) {
$builder->setExtensions(['json']);
$builder->resources('Students');
$builder->fallbacks();
});
$.get('/recent-dealers', function (data, status) {
console.log (JSON.parse(data)); });
});