You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加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();
                            }
                    }
        }
?>
问题原因
  1. PHP文件末尾的空白字符:所有PHP文件末尾的?>标签后如果存在换行、空格,会被当作输出内容混入JSON中,破坏JSON结构。设置Content-Type: application/json后,浏览器会严格校验JSON格式,这些空白字符就会触发解析错误。
  2. 异常处理中的直接输出: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:41:38