PHP设Content-Type需在任何输出前用header()发送,如application/json;须确保UTF-8无BOM、json_encode加JSON_UNESCAPED_UNICODE选项并检查返回值;禁用缓存或强制下载需配合适当响应头;状态码须与响应体一致。

PHP 响应 Content-Type 怎么设才生效
不设或错设 Content-Type,浏览器可能乱解析 JSON、XML 或纯文本,尤其用 file_get_contents 或 AJAX 请求时容易卡在「响应不是预期格式」。关键不是 echo 什么,而是头信息得先发、且不能被输出缓冲或已有输出干扰。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 调用
header()必须在任何输出(包括空格、BOM、echo、print)之前,否则报Warning: Cannot modify header information - 常见格式写法:
header('Content-Type: application/json; charset=utf-8')、header('Content-Type: text/xml; charset=utf-8')、header('Content-Type: text/plain; charset=utf-8') - 如果用了框架(如 Laravel、ThinkPHP),别直接写
header(),改用框架的响应构造方法(如 Laravel 的response()->json()),否则可能被中间件覆盖 - 检查文件是否含 UTF-8 BOM:BOM 会隐式触发输出,导致
header()失败;用编辑器(如 VS Code)设为「UTF-8 无 BOM」保存
JSON 响应中文乱码或被转义怎么办
PHP json_encode() 默认不处理中文,会转成 \uXXXX;更隐蔽的问题是,若输入字符串本身是 GBK 编码或含非法 UTF-8 字节,json_encode() 返回 false,但你不检查就直接输出,结果是空响应。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 确保输入数据是合法 UTF-8:用
mb_convert_encoding($data, 'UTF-8', 'auto')预处理 - 加
JSON_UNESCAPED_UNICODE选项:echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) - 务必检查返回值:
$json = json_encode($data); if ($json === false) { http_response_code(500); die('JSON encode failed: ' . json_last_error_msg()); } - 不要用
iconv()或mb_convert_encoding()对已编码的 JSON 字符串再转码——那是对字节流操作,会破坏 JSON 结构
如何让 PHP 响应禁用缓存或强制下载
调试接口时发现数据没更新,可能是浏览器或代理缓存了响应;想让用户点击链接直接下载 CSV 或 PDF,又得靠响应头控制行为。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 禁用缓存常用组合:
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0')+header('Expires: 0')+header('Pragma: no-cache') - 强制下载文件:
header('Content-Type: application/octet-stream')+header('Content-Disposition: attachment; filename="data.csv"')+header('Content-Length: ' . filesize($filepath)) - 注意
Content-Length必须精确,多一个换行或空格都会导致下载中断;用ob_get_length()获取输出缓冲长度更稳妥(如果内容是动态生成的) - Apache 下若启用了
mod_expires,它可能覆盖 PHP 的Expires头,此时需在 .htaccess 中显式禁用:ExpiresActive Off
响应格式和 HTTP 状态码要配套
返回 404 却输出 JSON,前端 fetch 拿到 response.ok === false,但没解析 body 就抛错;返回 200 却塞了个错误结构,前端逻辑全乱。状态码不是装饰,它参与整个请求生命周期。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 出错时优先设状态码:
http_response_code(400)、http_response_code(401)、http_response_code(500),再输出错误 JSON,如{"error": "invalid_token"} - 不要只依赖
echo内容判断成败——前端应同时检查response.status和response.headers.get('Content-Type') - CLI 模式下
http_response_code()无效,仅影响 SAPI 层;命令行脚本返回结构化数据建议用 exit code + stdout,而非模拟 HTTP - 使用
fastcgi_finish_request()后续写日志或发消息时,不能再调用header()或修改响应体——它已发出
最常被忽略的是输出顺序和编码一致性:header → 编码转换 → json_encode → 输出,四步缺一不可,任意一步跨编码或提前输出,格式就不可控。别信“echo 一下试试”,得用 curl -I 或浏览器 Network 面板看真实响应头。











