添加AJAX相关HTTP头后PHP数组转JSON出现解析错误求助
问题
尝试从MySQL获取用户数据转成JSON供AJAX使用,原代码正常运行,但在index.php顶部添加以下HTTP头后,浏览器抛出SyntaxError: JSON.parse: unexpected character at line 5 column 1 of the JSON data错误:
header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: *"); header('Content-Type: application/json');
访问localhost/folder/index.php?request=users时,未加头部能正常显示JSON,添加后报错。环境:Linux版XAMPP(LAMPP)8.1.10,Ubuntu Server 22.04.1 LTS x86_64,Firefox 106.0.1。相关代码如下:
index.php
<?php header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: *"); header('Content-Type: application/json'); require 'config.php'; if($_SERVER['REQUEST_METHOD'] == "GET") { if(isset($_GET['request'])) { if($_GET['request'] == "user" && isset($_GET['name'])) { $test = new TestClass($_GET['name']); $detail = $test->get_detail(); echo json_encode($detail); } else if($_GET['request'] == "users") { $users = TestClass::get_users(); echo json_encode($users); } } } ?>
config.php
<?php $dbhost="localhost"; $dbname="ajax"; $dbuser="root"; $dbpassword=""; require 'test.class.php'; ?>
test.class.php
<?php class TestClass { private $name; function __construct($name) { $this->name = $name; } public function get_detail() { try { $conn = new PDO("mysql:host=".$GLOBALS['dbhost'].";dbname=".$GLOBALS['dbname'], $GLOBALS['dbuser'], $GLOBALS['dbpassword']); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare("SELECT * FROM users where username = ?"); $stmt->execute([$this->name]); $res = $stmt->fetch(); return array( "ID" => $res['ID'], "username" => $res['username'], "email" => $res['email'], "password" => $res['password'], ); }catch(PDOException $e) { echo $e->getMessage(); return array(); } } public static function get_users() { try{ $conn = new PDO("mysql:host=".$GLOBALS['dbhost'].";dbname=".$GLOBALS['dbname'], $GLOBALS['dbuser'], $GLOBALS['dbpassword']); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare("SELECT * FROM users"); $stmt->execute([]); $array = array(); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { array_push($array, array( "ID" => $row['ID'], "username" => $row['username'], "email" => $row['email'], "password" => $row['password'], )); } return $array; } catch(PDOException $e) { return array(); } } } ?>
问题原因
- PHP文件末尾的空白字符:所有PHP文件末尾的
?>标签后如果存在换行、空格,会被当作输出内容混入JSON中,破坏JSON结构。设置Content-Type: application/json后,浏览器会严格校验JSON格式,这些空白字符就会触发解析错误。 - 异常处理中的直接输出:
get_detail()方法的catch块里直接echo $e->getMessage();,如果触发数据库异常,错误信息会直接输出到响应中,导致返回内容不是纯JSON。
解决方法
1. 移除所有PHP文件末尾的?>标签
PHP不需要强制关闭标签,移除后可避免标签后的空白被输出。修改后各文件不再保留末尾的?>。
2. 修改异常处理逻辑,避免直接输出错误信息
把get_detail()和get_users()中的catch块改为将错误信息放入返回数组,而非直接echo:
catch(PDOException $e) { return array("error" => $e->getMessage()); }
3. 确保响应只输出JSON内容
在echo json_encode(...)后添加exit();,终止脚本执行,防止后续可能的意外输出。
修改后的完整代码示例
index.php
<?php header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: *"); header('Content-Type: application/json'); require 'config.php'; if($_SERVER['REQUEST_METHOD'] == "GET") { if(isset($_GET['request'])) { if($_GET['request'] == "user" && isset($_GET['name'])) { $test = new TestClass($_GET['name']); $detail = $test->get_detail(); echo json_encode($detail); exit(); } else if($_GET['request'] == "users") { $users = TestClass::get_users(); echo json_encode($users); exit(); } } }
test.class.php(关键修改部分)
<?php class TestClass { private $name; function __construct($name) { $this->name = $name; } public function get_detail() { try { $conn = new PDO("mysql:host=".$GLOBALS['dbhost'].";dbname=".$GLOBALS['dbname'], $GLOBALS['dbuser'], $GLOBALS['dbpassword']); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare("SELECT * FROM users where username = ?"); $stmt->execute([$this->name]); $res = $stmt->fetch(); return array( "ID" => $res['ID'], "username" => $res['username'], "email" => $res['email'], "password" => $res['password'], ); }catch(PDOException $e) { return array("error" => $e->getMessage()); } } public static function get_users() { try{ $conn = new PDO("mysql:host=".$GLOBALS['dbhost'].";dbname=".$GLOBALS['dbname'], $GLOBALS['dbuser'], $GLOBALS['dbpassword']); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $conn->prepare("SELECT * FROM users"); $stmt->execute([]); $array = array(); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { array_push($array, array( "ID" => $row['ID'], "username" => $row['username'], "email" => $row['email'], "password" => $row['password'], )); } return $array; } catch(PDOException $e) { return array("error" => $e->getMessage()); } } }
内容的提问来源于stack exchange,提问作者Tommaso Sana
相关产品推荐
相关产品推荐

