我的控制器中有run
任务。我希望它返回JSON数据。就目前而言,我将我的JSON数据包装在模板HTML中。如何告诉Joomla只从控制器返回JSON数据?这是我的功能:
public function run ( ) {
JFactory::getDocument()->setMimeEncoding( 'application/json' );
JResponse::setHeader('Content-Disposition','attachment;filename="progress-report-results.json"');
JRequest::setVar('tmpl','component');
$data = array(
'foo' => 'bar'
);
echo json_encode( $data );
}
然后返回:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" dir="ltr">
...
</head>
<body class="contentpane">
<div id="system-message-container">
</div>
{"foo":"bar"}
</body>
</html>
我想得到:
{"foo":"bar"}
答案 0 :(得分:16)
您无需构建特殊的JSON视图(view.json.php
;或控制器progressreports.json.php
)来实现这一目标。您唯一要做的就是回显JSON字符串并关闭应用程序。
public function run( )
{
JFactory::getDocument()->setMimeEncoding( 'application/json' );
JResponse::setHeader('Content-Disposition','attachment;filename="progress-report-results.json"');
$data = array(
'foo' => 'bar'
);
echo json_encode( $data );
JFactory::getApplication()->close(); // or jexit();
}
如果要提供带有HTML和JSON输出的相同函数(由调用者选择),则只需要一个单独的视图(或控制器)。
答案 1 :(得分:2)
得到了答案。
我需要制作一个新的控制器。在我的情况下调用了原始控制器,progressreports.php - 我创建了一个名为progressreports.raw.php的新控制器。
然后在调用url时,添加format = raw。即。
index.php?option=com_foo&task=progressreports.run&format=raw
答案 2 :(得分:2)
您需要使用jexit()返回没有任何Joomla输出的json数据。
public function run ( ) {
$data = array(
'foo' => 'bar'
);
echo json_encode( $data );
jexit();
}
答案 3 :(得分:1)
根据你正在做的事情,你可能想制作一个json文档,whatever.json.php而不是whatever.html.php。
答案 4 :(得分:1)
我检查了接受的答案,它与joomla 3.4.3不兼容。如果有人有同样的问题,这里是低joomla版本的解决方案:
$data = array(
'foo' => 'bar'
);
header('content-type: application/json; charset=utf-8');
echo json_encode($data);
JFactory::getApplication()->close();
仅当您要提供要下载的文件时才需要内容处置标题。
关: 我只是想结束这个项目并喝一些想忘了它。即使从头开始并编写新的CMS也不会那么痛苦。 :S
答案 5 :(得分:0)
我不喜欢JResponseJson,也喜欢为下一个请求排队消息,所以我在组件的主控制器上创建了以下方法:
public function returnJson($data)
{
$app = Factory::getApplication();
// Persist messages if they exist. (Same as CMSApplication->redirect)
$session = \JFactory::getSession();
$session->set('application.queue', $app->getMessageQueue());
// Send json mime type.
$app->mimeType = 'application/json';
$app->setHeader('Content-Type', $app->mimeType . '; charset=' . $app->charSet);
$app->sendHeaders();
echo json_encode($data);
$app->close();
}
在控制器或子控制器的任何任务中,您现在可以执行以下操作:
public function sampleTask()
{
$app = Factory::getApplication();
$app->enqueueMessage("Done (for the next user's request)", 'success');
$this->returnJson("json data");
}
答案 6 :(得分:0)
您必须将参数 &format=json 添加到您的 URL。 这告诉系统您正在等待 json 响应。系统将呈现 JsonDocument 并发送正确的浏览器标头作为响应。
index.php?option=com_foo&task=report.run&format=json
class Report extends BaseController {
public function run() {
$data = [
'foo' => 'bar'
];
$response = new ResponseJson($data);
echo $response;
}
}
无需使用 $app->close(); 关闭应用程序,因为 Joomla 的架构会为您处理。
如果关闭应用程序,您将在渲染过程中遗漏很多东西。许多事件不会被触发。此外,您必须手动发送内容类型的标头。
您的代码应该如下所示。这种方法不推荐。
class Report extends BaseController {
public function run() {
$this->app->mimeType = 'application/json';
$this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet);
$this->app->sendHeaders();
$data = [
'foo' => 'bar'
];
$response = new ResponseJson($data);
echo $response;
$this->app->close();
}
}