必须设置header('content-type: application/json; charset=utf-8'),否则客户端误解析导致json解析失败、中文乱码或压缩失效;需避免bom、输出前置和缓冲干扰,通过chrome network或curl -i验证响应头。

PHP输出JSON时必须设置Content-Type: application/json
不加header(),浏览器或前端框架(如axios、fetch)很可能把响应当成text/html或text/plain处理,导致解析失败、response.json()抛错,或Vue/React中数据绑定异常。
常见错误现象:Uncaught (in promise) SyntaxError: Unexpected token ——本质是服务器返回了HTML(比如PHP错误页或空白页),而非合法JSON。
- 必须在
echo或json_encode()前调用header('Content-Type: application/json; charset=utf-8') -
charset=utf-8不是可选的:省略可能导致中文乱码,尤其在旧版IE或某些HTTP客户端中 - 不能在输出任何内容(包括空格、BOM、
echo '')后再调用header(),否则触发Warning: Cannot modify header information
为什么application/json比text/plain更关键
有些开发者误以为只要json_encode()输出了格式正确的字符串就行,但MIME类型才是客户端决定“如何解析响应”的第一依据。
对比影响:
立即学习“PHP免费学习笔记(深入)”;
-
Content-Type: text/plain→ 浏览器不自动解析JSON,fetch().then(r => r.json())会失败 -
Content-Type: application/json→ 浏览器/客户端明确知道这是JSON,允许直接调用.json(),且后端框架(如Laravel、Symfony)的中间件或前端调试工具(如Chrome Network面板)能正确高亮和校验结构 - 部分CDN或反向代理(如Nginx)会根据
Content-Type决定是否压缩响应;设错类型可能跳过gzip压缩,影响传输性能
实际代码中容易漏掉的三个点
即使写了header(),仍可能因细节失效:
- PHP文件开头存在UTF-8 BOM(尤其是Windows编辑器保存时默认添加),会导致
header()调用失败——用编辑器转为“UTF-8无BOM”格式 - 启用了输出缓冲(
ob_start())但未显式ob_end_flush(),或有未捕获的警告(E_WARNING)被输出到响应体,破坏JSON结构 - 使用
exit(json_encode(...))但没设header:PHP会立即终止,但header()必须提前执行,exit()里不能补救
推荐写法:
header('Content-Type: application/json; charset=utf-8');
http_response_code(200);
echo json_encode(['status' => 'ok', 'data' => $result], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
调试时怎么看header是否生效
别只信浏览器地址栏或var_dump()结果。真正在意的是网络层实际发出的响应头:
- Chrome DevTools → Network → 点开请求 → Headers → Response Headers → 查看
content-type值 - 命令行验证:
curl -I http://localhost/api.php(注意大写-I只取头) - 如果看到
content-type: text/html或压根没content-type,说明header()没执行成功,回头检查输出前置、BOM、错误抑制(@)等问题
最常被忽略的是:JSON本身合法,但header没发出去,整个响应就失去了语义。这比JSON格式错误更难定位,因为控制台报错指向前端解析逻辑,而非后端配置。











