React与PHP登录交互报错:JSON解析失败及参数未定义求助
解决React调用PHP登录接口的JSON解析及参数未定义问题
问题现象
使用React编写登录校验逻辑时,调用PHP接口出现JSON.parse: unexpected end of data at line 1 column 2 of the JSON data错误;移除PHP中参数存在性判断并将前端res.json()改为res.text()后,收到Undefined array key "Username"和Undefined array key "Password"警告。
错误原因
- React端逻辑顺序错误:先调用
checkLogin发送请求,后往FormData添加用户名和密码,导致接口收到空数据;同时手动设置Content-Type: application/json,但实际发送的是FormData,PHP无法通过$_POST解析参数。 - PHP端输出不规范:参数不存在时未输出合法JSON,导致前端解析失败;存在SQL注入风险,且未处理CORS预检的OPTIONS请求。
修复步骤
1. React端代码修正
调整请求逻辑顺序,移除错误的Content-Type设置:
const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const checkLogin = async (formData) => { await fetch("http://localhost/innovate_recipe/Backend/VerifyLogin.php", { method: 'POST', // 移除手动设置的Content-Type,fetch发送FormData时会自动配置正确请求头 body: formData, }) .then((res) => res.json()) .then((data) => console.log(data)) .catch((err) => { console.log(err.message); }); }; const handleSubmit = (event) => { event.preventDefault(); // 每次提交创建新的FormData,避免复用旧数据 const fData = new FormData(); fData.append('Username', username); fData.append('Password', password); checkLogin(fData); // 先填充数据再发送请求 };
2. PHP端代码修正
规范JSON输出,处理CORS预检,修复SQL注入风险:
<?php session_start(); include 'DbConnect.php'; // 处理CORS预检OPTIONS请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header('Access-Control-Allow-Origin: http://localhost:3000'); header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE"); header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With"); exit(); } // 常规请求的CORS及JSON响应头 header('Access-Control-Allow-Origin: http://localhost:3000'); header("Content-Type: application/json; charset=UTF-8"); $con = mysqli_connect($servername, $user, $password, $database); // 检查数据库连接 if (!$con) { echo json_encode(["status" => "error", "message" => "数据库连接失败"]); exit(); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_POST['Username']) && isset($_POST['Password'])) { $username = $_POST['Username']; $password = $_POST['Password']; // 使用预处理语句防止SQL注入 $sql = "SELECT * FROM login WHERE Username=? and Password=?"; $stmt = mysqli_prepare($con, $sql); mysqli_stmt_bind_param($stmt, "ss", $username, $password); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if (mysqli_num_rows($result) == 1) { $_SESSION['username'] = $username; echo json_encode(["status" => "success", "username" => $username]); } else { echo json_encode(["status" => "error", "message" => "Wrong username or password"]); } mysqli_stmt_close($stmt); } else { // 参数缺失时返回JSON格式错误信息 echo json_encode(["status" => "error", "message" => "缺少必要参数"]); } } else { echo json_encode(["status" => "error", "message" => "不支持的请求方法"]); } mysqli_close($con); ?>
关键说明
- React端:发送
FormData时不要手动设置Content-Type,浏览器会自动添加multipart/form-data及边界标识,确保PHP能正确解析$_POST参数。 - PHP端:所有分支必须输出合法JSON,避免警告或错误信息混入响应内容;使用预处理语句彻底规避SQL注入风险;处理OPTIONS预检请求解决跨域问题。
内容的提问来源于stack exchange,提问作者Tuan Dat
相关产品推荐
相关产品推荐

