jQuery AJAX实现滑动验证码登录时出现JSON解析失败问题
问题根源
你碰到的JSON解析失败是以下3个问题共同导致的:
- 前端AJAX配置错误,声明了发送JSON格式但实际发送的是表单格式,导致后端接收不到参数
- 后端PHP未开启session就调用
$_SESSION变量,抛出PHP警告污染了返回的JSON格式 - MySQLi预处理查询执行后未同步结果集,导致
num_rows永远返回0,逻辑执行不符合预期
前端修复方案
把AJAX配置里的contentType: "application/json"删掉即可,你传普通JS对象的时候jQuery默认会用application/x-www-form-urlencoded格式发送,正好匹配PHP的$_POST接收逻辑:
$.ajax({ url: 'ajax_requests/login_ajax.php', type: 'POST', cache: false, data: { 'username': $('#username').val(), 'password': $('#password').val() }, // 删掉原有的contentType: "application/json"配置 dataType: 'JSON', // 剩余的success、error逻辑保持不变即可 success: function(response) { // ...原有逻辑 }, error: function(jqXHR, exception) { // ...原有逻辑 } });
后端修复方案
需要添加3处修改:
- 代码最开头加
session_start()开启session,才能正常操作$_SESSION变量 - 预处理执行后调用
store_result()同步结果集,才能正确获取num_rows的数值 - 添加参数校验,避免未接收到参数时抛出PHP警告污染返回内容
修复后的完整PHP代码:
<?php session_start(); // 新增:开启session header('Content-Type: application/json'); $conn = mysqli_connect("localhost","root","","shopperapproved"); // 新增:参数校验,避免未传参时抛出警告 if (!isset($_POST['username']) || !isset($_POST['password'])) { echo json_encode(["status" => "0"]); exit; } $username = $conn->real_escape_string($_POST['username']); $password = $conn->real_escape_string($_POST['password']); $password_crypted = hash('sha256', $password); $_login = $conn->prepare("SELECT * FROM `admin_users` WHERE `username`=? AND `password`=?"); $_login->bind_param("ss", $username, $password_crypted); $_login->execute(); $_login->store_result(); // 新增:同步结果集 if ($_login->num_rows > 0) { $_SESSION['login_session'] = hash('sha256', rand(6453, 891673)); if (isset($_SESSION['login_session'])) { $result = array("status" => "1"); echo json_encode($result); } else { $result = array("status" => "0"); echo json_encode($result); } } else { $result = array("status" => "0"); echo json_encode($result); } $_login->close(); ?>
补充排查方法:如果修改完成后仍出现相同报错,可以在error回调中打印
console.log(jqXHR.responseText)查看服务端实际返回的完整内容,就能直接定位是否有多余的PHP报错信息输出污染了JSON格式。
内容的提问来源于stack exchange,提问作者JohnBowls
相关产品推荐
相关产品推荐

