响应类型已从JSON更改为HTML,且未更改任何代码

时间:2018-09-05 15:16:31

标签: php json cakephp cakephp-2.0

我在CakePHP 2.x中有一个旧版应用程序

它在Controller中有一个方法,该方法以如下结构输出JSON:

{"id":59,"name":"Association of Southeast Asian Nations (ASEAN)","n_grouptags":1}

控制器方法使用$this->response->type('json');来设置对content-type的响应中的application/json; charset=UTF-8。一切都很好。

我注意到的是,如果返回的数据超过一定长度,则content-type将设置为text/html; charset=UTF-8 而无需更改代码

我在下面提供了一些截图,其中包括响应类型。

少量数据(内容类型= application/json-预期):

enter image description here

enter image description here

更多数据(内容类型= text/html-意外):

enter image description here

enter image description here

在两种情况下,我都使用https://jsonlint.com/

检查了JSON是否有效

这是为什么?它是否取决于浏览器如何对待响应的长度,或者这是一个CakePHP问题?

负责输出的PHP如下-但在上面给出的2个不同输出之间未对此进行任何更改

    $this->autoRender = false; // No View (template) is associated with this

    $out = []; // Reset

    // $tags is some data from a model
    foreach ($tags as $k => $v) {
        $n_grouptags = 123; // Actual number comes from a Model 
        $out[] = ['id' => $k, 'name' => $v, 'n_grouptags' => $n_grouptags];
    }

    $this->response->type('json'); // We *want* a JSON response

    echo json_encode($out, JSON_FORCE_OBJECT); // Encode $out (the output) as JSON

应用程序内的缓存已禁用:Configure::write('Cache.disable', true);

1 个答案:

答案 0 :(得分:0)

控制器动作不应回显数据,即使它在某些情况下(甚至在大多数情况下)都可以工作。输出不是来自渲染的视图模板的数据的正确方法是配置并返回响应对象(或字符串,但与3.x不兼容),或使用序列化的视图。

根本问题不是内容的长度,而是通常在响应对象可以发送标头之前输出数据,这将导致它们被忽略,一旦在响应发射器到达之前发送了单个字节,就会发生这种情况发挥作用。

由于您使用的是PHP输出缓冲和/或压缩(请参见output_buffering中的zlib.output_compressionphp.ini),这很可能仅在一定长度上发生,这将导致回传的数据将一直保留,直到超出缓冲区的存储能力为止(在大多数情况下通常为4096字节),或者显式刷新缓冲区(在脚本执行结束时会自动发生)。

tl; dr,要进行快速修复,请配置并返回响应:

$this->response->body(json_encode($out, JSON_FORCE_OBJECT));
return $this->response;

另请参见