如何在 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' =&gt; $actions[0]) ) 语句替换它们。

您也在测试$this-&gt;RequestHandler-&gt;isGet()。请尝试测试$this-&gt;RequestHandler-&gt;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 返回正确的内容类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 CakePHP 2.2 控制器返回 JSON?

如何在 CakePHP 2 中为 3 个树状连接表保存数据

如何在 cakephp 中为不同的模型设置不同的布局

CakePHP 3如何使用REST以正确的方式保存相关关联1:N?

在 CakePHP 3 中为文章添加评论

如何在 ApiController 中为单个方法返回 JSON?