我在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
- 预期):
更多数据(内容类型= 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);
控制器操作不应该回显数据,即使它可能在某些情况下工作,甚至可能在大多数情况下工作。输出不是来自渲染视图模板的数据的正确方法是配置和返回响应对象(或字符串,但不与3.x向前兼容),或使用序列化视图。
根问题不是内容的长度,而是通常在响应对象发送标头之前输出数据,这将导致它们被忽略,一旦在响应发射器进入播放之前甚至发送单个字节,这将发生。
它很可能只发生一定长度,因为你正在使用PHP输出缓冲和/或压缩(参见output_buffering
中的zlib.output_compression
和php.ini
),这将导致回显数据被阻止,直到超出缓冲存储能力(在大多数情况下通常为4096字节),或者显式刷新缓冲区(这将在脚本执行结束时自动发生)。
tl; dr,用于快速修复,配置并返回响应:
$this->response->body(json_encode($out, JSON_FORCE_OBJECT));
return $this->response;
也可以看看