本地前后端对接异常:LiveServer+XAMPP接口请求返回空内容
前后端对接异常排查求助
本地搭建前后端项目时遇到对接问题:前端用VSCode的LiveServer部署(解决图片/模块加载的CORS问题),后端基于XAMPP,文件放在服务器目录。当前端提交登录表单,通过AJAX请求http://localhost/web/back/public/login时,接口返回空文件。为排查问题,在LoginController中添加了测试函数hola(),但该函数未被触发,说明请求根本没到控制器。
前端请求代码(login.js)
$(document).ready(function() { $('#login-form').submit(function(event) { event.preventDefault(); const username = $('#email').val(); const password = $('#password').val(); // 发送登录AJAX请求 $.ajax({ url: 'http://localhost/web/back/public/login', method: 'POST', dataType: 'json', contentType: 'application/json', error: function(error) { console.error(error); } }); }); });
注:原代码中error回调存在语法缺失,已补全error: function(error)部分
后端入口文件(Index.php)
<?php include('../app/routes/Login.php'); foreach ($routes as $url => $route) { $method = $route[0]; $controller = $route[1]; $action = $route[2]; error_log("处理路由: $url"); error_log("请求方法: " . $_SERVER['REQUEST_METHOD']); error_log("请求URI: " . $_SERVER['REQUEST_URI']); if ($_SERVER['REQUEST_METHOD'] === $method && preg_match('#^'.$url.'$#', $_SERVER['REQUEST_URI'])) { error_log("匹配到路由,调用控制器: $controller 方法: $action"); $controller = new $controller(); $controller->$action(); break; } } ?>
后端路由文件(Login.php)
<?php use back\app\controllers\LoginController; $routes = [ '/login' => ['POST', LoginController::class, 'login'], '/logout' => ['POST', LoginController::class, 'logout'] ]; ?>
后端控制器文件(LoginController.php)
<?php session_start(); require_once '../../tools/connection.php'; // 错误:类定义外调用$this->hola(),此处代码会直接报错中断执行 // $this->hola(); class LoginController { function hola(){ echo("HOLA"); } public function login() { $data = json_decode(file_get_contents('php://input'), true); $username = $data['username']; $password = $data['password']; $authResult = $this->authenticate($username, $password); // 修正:authenticate返回数组而非布尔值,需判断是否为错误结果 if (!isset($authResult['error'])) { session_start(); $_SESSION['logged_in'] = true; $_SESSION['username'] = $username; $response = [ 'success' => true, 'message' => '登录成功' ]; header('Content-Type: application/json'); echo json_encode($response); } else { $response = [ 'success' => false, 'message' => $authResult['error'] ]; header('Content-Type: application/json'); http_response_code($authResult['code']); echo json_encode($response); } } public function logout() { // 关闭会话 session_start(); session_destroy(); $response = [ 'success' => true, 'message' => '注销成功' ]; header('Content-Type: application/json'); echo json_encode($response); } private function authenticate(string $username, string $password) { if (empty($username) || empty($password)) { return ['error' => '用户名或密码为空', 'code' => 401]; } $conn = connect(); $sql = "SELECT p.*, CASE WHEN a.IdPersona IS NOT NULL THEN 'Administrador' WHEN t.IdPersona IS NOT NULL THEN 'Tutor' WHEN al.IdPersona IS NOT NULL THEN 'Alumno' ELSE NULL END AS Rol FROM Persona p LEFT JOIN Administrador a ON a.IdPersona = p.IdPersona LEFT JOIN Tutor t ON t.IdPersona = p.IdPersona LEFT JOIN Alumno al ON al.IdPersona = p.IdPersona WHERE p.CorreoElectronico = :username"; $stmt = $conn->prepare($sql); $stmt->bindParam(':username', $username); $stmt->execute(); $result = $stmt->fetch(); if (!$result || $result['Password'] !== $password) { return ['error' => '用户名或密码错误', 'code' => 401]; } switch ($result['Rol']) { case 'Administrador': $userType = 'administrador'; break; case 'Tutor': $userType = 'tutor'; break; case 'Alumno': $userType = 'alumno'; break; default: return ['error' => '用户类型不存在', 'code' => 401]; } return [ 'id' => $result['IdPersona'], 'nombre' => $result['Nombre'], 'apellido' => $result['Apellido'], 'email' => $result['CorreoElectronico'], 'rol' => $userType ]; } }
注:原代码存在两处致命错误:1. 类定义外部调用$this->hola(),会直接触发Fatal Error导致脚本中断;2. login方法中错误将authenticate的数组返回值当作布尔值判断
异常截图
- 浏览器控制台错误:

- Preflight请求:

- XHR请求:

排查解决步骤
- 修复控制器致命错误:删除
LoginController.php中类定义外的$this->hola();代码,该语句在类实例化前调用,直接导致脚本崩溃,无法处理请求。 - 修正登录逻辑判断:
authenticate方法返回的是数组而非布尔值,需修改login方法中的判断逻辑,检查返回结果是否包含error字段。 - 检查路由匹配:查看XAMPP的错误日志(
xampp/apache/logs/error.log),确认Index.php中输出的error_log内容,判断请求URI是否与路由/login匹配。当前请求URI是/web/back/public/login,而路由定义的是/login,正则匹配#^/login$#无法匹配完整URI,需调整路由规则为#^/web/back/public/login$#或者修改路由定义为相对路径。 - 处理CORS问题:从Preflight请求截图看,需在后端添加CORS响应头,允许前端域名的跨域请求。可在Index.php顶部添加:
header("Access-Control-Allow-Origin: *"); // 生产环境建议指定具体域名 header("Access-Control-Allow-Methods: POST, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type"); // 处理OPTIONS预请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { exit(0); }
- 补全AJAX请求数据:前端AJAX未发送
username和password数据,需添加data参数:
data: JSON.stringify({ username: username, password: password }),
内容的提问来源于stack exchange,提问作者Ivan Martin Blanco
相关产品推荐
相关产品推荐

