如何在 CakePHP 中为 JSON 返回正确的内容类型?
Posted
技术标签:
【中文标题】如何在 CakePHP 中为 JSON 返回正确的内容类型?【英文标题】:How to return the correct content-type for JSON in CakePHP? 【发布时间】:2010-11-16 14:44:51 【问题描述】:我正在尝试为通过 AJAX GET 请求访问的 JSON 响应设置内容类型标头。我已经关注博客和面包店的教程,但我总是从 Cakephp 收到“文本/html”。如何正确设置 content-type 标头?
这是我目前的代码:
public function admin_controller_actions_ajax()
Configure::write('debug', 0);
if ($this->RequestHandler->isGet())
$this->autoRender = FALSE;
$aco_id = $this->params['url']['aco_id'];
$aro_id = $this->params['url']['aro_id'];
assert('$aco_id != NULL && $aro_id != NULL &&
is_numeric($aco_id) && is_numeric($aro_id)');
$actions = $this->Resource->getActionsForController($aco_id, $aro_id);
assert('is_array($actions) && is_array($actions[0])');
/* I made RequestHandler part of the $components property */
$this->RequestHandler->setContent('json');
$this->RequestHandler->respondAs('json'); /* I've tried 'json', 'JSON', 'application/json' but none of them work */
$this->set('json_content', json_encode(array('response' => $actions[0])));
$this->layout = NULL;
$this->render('/json/default');
/* json/default.ctp */
<?php echo $json_content; ?>
任何帮助将不胜感激。
谢谢,
-- 艾萨克
【问题讨论】:
你在你的 routes.php 文件中使用 Router::parseExtensions() 吗?如果是,则必须在 app/config/core.php 中将“debug”设置为 0,以使其响应正确的内容类型。 不,我不使用 Router::parseExtensions() 但无论如何我在请求中将 debug 设置为 0。 【参考方案1】:我在我的所有项目中都进行 Ajax 调用以检索 JSON 内容,而您在这里所做的大部分工作我从未做过。我的控制器代码的范围如下所示:
public function do_something_ajaxy()
Configure::write ( 'debug', 0 );
$this->autoRender = false;
/** Business logic as required */
echo json_encode ( $whatever_should_be_encoded );
我通过 jQuery 进行 Ajax 调用,所以我认为 可以 有所作为,但这会让我感到惊讶。在这种情况下,您的问题似乎出在处理程序中,而不是调用方。我建议删除第 17-23 行并用简单的 echo json_encode ( array('response' => $actions[0]) )
语句替换它们。
您也在测试$this->RequestHandler->isGet()
。请尝试测试$this->RequestHandler->isAjax()
。我不确定 Ajax 调用是否被它们的类型和方法识别。
【讨论】:
我之前尝试过这样做——我只是有'return json_encode'(我也尝试过'echo json_encode')。我在 IRC 频道中被告知这是一种不好的做法,而“正确的方法”是使用视图。我不同意,但我还是照做了。我将测试 isAjax,但鉴于我的 ajax 调用是一个 get 请求,isGet 也应该可以工作。我还使用 jQuery 进行 ajax 调用。 我刚刚尝试了您的建议(我简化了所有内容以回显 json_encode 并使用 isAjax 而不是 isGet),但我仍然返回 'text/html'。 对不起,艾萨克。我忘了循环回来。只要内容本身是有效的 JSON,内容类型就无关紧要。我避免查看此类内容,因为它是一个额外的文件,基本上什么都不做。我有混乱的问题。 :-) 对我来说,Configure::write ( 'debug', 0 );
是神奇的调味汁。注:根据@Ajtacka's answer,Configure::write ( 'debug', 1 );
也可以使用【参考方案2】:
阅读this和this后,我得到以下返回“Content-Type:application/json”:
Configure::write('debug', 0);
$this->RequestHandler->respondAs('json');
$this->autoRender = false;
echo json_encode($data);
使用 JQuery 的 $.getJSON 方法,我仍然得到 p>
Resource interpreted as image but transferred with MIME type text/html.
但至少我的数据正在解析。
【讨论】:
我最近在 Cake 2.0 中使用了这个方法(虽然把这段代码移到了 AppController 中的一个函数中,这样任何控制器都可以使用它而无需重复)。它似乎运行良好,并允许 jQuery (1.7) 将内容自动检测为 JSON。【参考方案3】:我也遇到了这个问题,通过以下方式解决了:
$this->RequestHandler->respondAs('text/x-json');
还要确保配置文件中的“调试”设置为小于 2,否则将不会设置标头。
【讨论】:
您对 debug $this->RequestHandler->respondAs('json'); 应该是正确的 - 这对应于设置application/json
的标题,即most appropriate header for JSON【参考方案4】:
我不确定(老实说,我从未使用过 CakePHP),但您可能想尝试在 setContent 方法中指定第二个参数。
替换这个:
$this->RequestHandler->setContent('json')
用这个:
$this->RequestHandler->setContent('json', 'text/x-json');
请参阅this file 了解示例..
【讨论】:
我刚刚尝试过这个(我之前尝试过类似的次要参数,但我想我会再试一次)但它不起作用。我仍然得到'text/html'返回。 我也是。我使用它并尝试使用以下命令强制响应类型: $this->RequestHandler->respondAs('json');都不适合我。【参考方案5】:我遇到了与原始海报相同的问题,对我有用的是遵循 Rob Wilkerson 的建议,但也要确保我正在使用
jQuery.ajax()
而不是
jQuery.get()
或
jQuery.post()
jQuery.ajax() 允许您将数据类型设置为“json”,而其他两个似乎根本不允许您设置数据类型。当我将 AJAX 请求中的数据类型设置为“json”时,一切正常。
【讨论】:
您实际上可以在.post()
和 .get()
中指定数据类型,请参阅文档(截至 2011 年 12 月)。 api.jquery.com/jQuery.postapi.jquery.com/jQuery.get以上是关于如何在 CakePHP 中为 JSON 返回正确的内容类型?的主要内容,如果未能解决你的问题,请参考以下文章