跨域返回json时必须同时设置content-type为application/json且含charset=utf-8、cors响应头(如access-control-allow-origin),并确保json格式正确、无输出缓冲干扰。

跨域请求返回 JSON 数据时,Content-Type 必须设为 application/json,否则前端 fetch 或 axios 可能解析失败或触发 TypeError: Failed to fetch —— 这不是 CORS 配置没加全,而是响应头语义错误。
PHP 输出 JSON 前必须调用 header()
PHP 默认输出 text/html,即使你用了 json_encode(),浏览器仍按 HTML 解析。必须在 echo 或 print 前设置:
header('Content-Type: application/json; charset=utf-8');- 不能写成
text/plain、text/html或漏掉charset=utf-8(中文会乱码) - 如果用了框架(如 Laravel、ThinkPHP),优先走框架的 JSON 响应方法(如
response()->json()),避免手动header()被覆盖
跨域头和 JSON 头要同时存在,且顺序无关但缺一不可
CORS 头(如 Access-Control-Allow-Origin)和 Content-Type 是独立生效的两个响应头,前端拿到响应时两者都需正确:
- 必须设置
header('Access-Control-Allow-Origin: *');或具体域名(如https://example.com) - 若前端带凭据(
credentials: 'include'),则Access-Control-Allow-Origin不能为*,且需加header('Access-Control-Allow-Credentials: true'); -
header('Content-Type: application/json; charset=utf-8');和 CORS 头谁先谁后不影响结果,但都不能被后续代码(比如框架自动输出)覆盖
常见错误:JSON 字符串被二次编码或含非法字符
即使 Content-Type 正确,JSON 格式出错也会导致前端解析失败(SyntaxError: Unexpected token):
立即学习“PHP免费学习笔记(深入)”;
- 不要手动拼接 JSON 字符串,用
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) - 确保
$data中不含资源类型(如 MySQL result resource)、循环引用对象,否则json_encode()返回false - 输出前检查:
if (json_last_error() !== JSON_ERROR_NONE) { http_response_code(500); die('Invalid JSON'); } - 避免在
json_encode()后再加换行、空格、BOM 或调试var_dump()输出
最易被忽略的是:PHP 输出缓冲(output buffering)开启时,header() 可能因已有输出而失败,建议开头加 if (headers_sent()) { die('Headers already sent'); } 快速定位。











