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

如何从MVC控制器正确获取JSON数据?返回含HTML问题排查

问题:AJAX请求返回包含JSON的完整HTML页面,而非预期的纯JSON数据

我通过以下jQuery AJAX代码向MVC控制器请求数据:

$(document).on("click", "#btn-register", function (event) {
  event.preventDefault();

  $.ajax({
    url: baseUrl() + "/users/register",
    type: "POST",
    dataType: "JSON",
    data: {
      name: $("#name").val(),
      email: $("#email-address").val(),
      password: $("#password").val(),
      confirm: $("#confirm-password").val(),
    },
    success: function (data) {
      console.log(data);
    },
    error: function (message) {
      console.log(message.responseText);
    },
  });
});

对应的PHP MVC控制器代码:

public function register () {

    $result = [];

    if ($_SERVER['REQUEST_METHOD'] === 'POST') {

      $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS);

      $data = [
        'name'                    => trim($_POST['name']),
        'email'                   => trim($_POST['email']),
        'password'                => trim($_POST['password']),
        'confirm_password'        => trim($_POST['confirm']),
        'name_error'              => '',
        'email_error'             => '',
        'password_error'          => '',
        'confirm_password_error'  => ''
      ];

      $data['name_error'] = (empty($data['name'])) ? 'Please enter name' : '';
      $data['confirm_password_error']  = (empty($data['confirm_password']))   ? 'Please confirm password' : '';

      if (empty($data['email']))
        $data['email_error'] = 'Please enter email';
      else if ($this->user->findUserByEmail($data['email']) === true)
        $data['email_error'] = 'Email is already taken';

      if (empty($data['password']))
        $data['password_error'] = 'Please enter a password';
      else if (strlen($data['password']) < self::$password_length)
        $data['password_error'] = 'Password must be at least ' . self::$password_length . ' characters long';
      else if ($data['password'] != $data['confirm_password'])
        $data['password_error'] = 'Password did not match';

      if (
          empty($data['name_error']) && 
          empty($data['email_error']) && 
          empty($data['password_error']) && 
          empty($data['confirm_password_error'])) {
        
          $result['status'] = 'valid inputs';
          echo json_encode($result);
      }

    } else {
      
      $data = [
        'name'                    => '',
        'email'                   => '',
        'password'                => '',
        'confirm_password'        => '',
        'name_error'              => '',
        'email_error'             => '',
        'password_error'          => '',
        'confirm_password_error'  => ''
      ];

    }

    $this->view('users/register', $data);
    
  }

点击#btn-register按钮后,error回调输出包含{"status":"valid inputs"}的完整HTML页面,而非仅JSON数据。


原因分析

核心问题是控制器输出JSON后未终止脚本执行:当输入验证通过时,你通过echo json_encode($result)输出了JSON字符串,但代码继续执行到末尾的$this->view('users/register', $data),这会渲染并输出整个注册页面的HTML代码。最终响应内容是JSON字符串 + HTML代码的混合体,jQuery的dataType: "JSON"无法解析这种混合内容,因此触发error回调。


解决方法

1. 输出JSON后立即终止脚本

在echo json_encode($result);之后添加exit;或die();,阻止后续代码执行,确保仅输出JSON数据:

if (
    empty($data['name_error']) && 
    empty($data['email_error']) && 
    empty($data['password_error']) && 
    empty($data['confirm_password_error'])) {
  
    $result['status'] = 'valid inputs';
    echo json_encode($result);
    exit; // 终止脚本,不再执行后续的view渲染
}

2. (可选)设置正确的响应头

为了更规范地告诉客户端返回的是JSON数据,在输出JSON之前添加Content-Type响应头:

if (
    empty($data['name_error']) && 
    empty($data['email_error']) && 
    empty($data['password_error']) && 
    empty($data['confirm_password_error'])) {
  
    header('Content-Type: application/json'); // 设置JSON响应头
    $result['status'] = 'valid inputs';
    echo json_encode($result);
    exit;
}

这样修改后,AJAX请求会收到纯JSON数据,触发success回调并正确解析数据。


内容的提问来源于stack exchange,提问作者Jhay Lawrence

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 20:14:54