首页 > 解决方案 > 响应类型从 JSON 更改为 HTML,无需任何代码更改

问题描述

我在 CakePHP 2.x 中有一个遗留应用程序

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

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

用于在响应中$this->response->type('json');设置 的控制器方法。都好。content-typeapplication/json; charset=UTF-8

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

我在下面包含了一些显示这一点的屏幕截图,包括响应类型。

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

在此处输入图像描述

在此处输入图像描述

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

在此处输入图像描述

在此处输入图像描述

在这两种情况下,我都使用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);

标签: phpjsoncakephpcakephp-2.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;

也可以看看


推荐阅读