php - 响应类型从 JSON 更改为 HTML,无需任何代码更改
问题描述
我在 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;
也可以看看
推荐阅读
- json - 如何处理 Haskell 中 JSON 对象的可变性?
- java - 使用 Sikuli 和 Env.isLockOn(Key.NUM_LOCK) 单击图像不起作用
- javascript - 如何从带有参数的js文件调用javascript函数并从tsx文件返回数据?
- regex - 匹配特殊字符
- mercurial - 审查委员会 3 的 mercurial (hg) 扩展
- php - 如何使用 installed.json 恢复 composer.json 和 composer.lock?
- html - SVG 符号不显示渐变
- video - FFMPEG:不能再导出 >10k 像素的视频?
- javascript - WebGLSync 始终是 UNSIGNALED
- jquery-easyui - 如何翻译 EasyUI 日期框