React调用PHP存储数据时出现404错误,请求解决方案
问题解决方案
一、先解决404错误(核心问题)
你当前React项目跑在localhost:3000(React开发服务器端口),但PHP文件需要部署在XAMPP的Apache服务下(默认端口为localhost:80),两个服务的根目录完全独立,直接从3000端口请求PHP文件必然找不到。
步骤1:调整PHP文件位置
将saveCourses.php和show.php移动到XAMPP的htdocs文件夹中,建议在htdocs下新建api子文件夹存放这两个文件,最终路径为htdocs/api/。
步骤2:修改React中的请求路径
把App.js里的fetch路径替换为Apache服务的对应地址:
- 原
./Components/saveCourses.php改为/api/saveCourses.php - 原
./Components/show.php改为/api/show.php
可选:配置代理避免跨域(推荐)
直接使用绝对路径可能触发跨域问题,在React项目根目录新建setupProxy.js文件,内容如下:
const { createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function(app) { app.use( '/api', createProxyMiddleware({ target: 'http://localhost', changeOrigin: true, }) ); };
配置后,React中请求/api/xxx.php时会自动转发到Apache的localhost/api/xxx.php,无需修改绝对路径,同时规避跨域问题。
二、修复PHP代码的安全与功能问题
你的PHP代码直接拼接SQL语句,存在严重的SQL注入风险,且未处理JSON解析失败、数据库连接关闭等场景,修改后的代码如下:
<?php header('Content-Type: application/json'); // 设置响应为JSON格式 $servername = "localhost"; $username = "root"; $password = ""; $dbname = "courses"; // 创建数据库连接 $conn = mysqli_connect($servername, $username, $password, $dbname); if (!$conn) { echo json_encode(['status' => 'error', 'message' => "连接失败: " . mysqli_connect_error()]); exit; } // 读取并解析JSON数据 $data = file_get_contents("php://input"); $courses = json_decode($data, true); // 检查JSON解析是否成功 if (!$courses || !is_array($courses)) { echo json_encode(['status' => 'error', 'message' => "无效的数据格式"]); mysqli_close($conn); exit; } // 使用预处理语句避免SQL注入 $stmt = mysqli_prepare($conn, "INSERT INTO tbl (coursename, isConfirmed) VALUES (?, ?)"); if (!$stmt) { echo json_encode(['status' => 'error', 'message' => "预处理语句创建失败: " . mysqli_error($conn)]); mysqli_close($conn); exit; } // 绑定参数 mysqli_stmt_bind_param($stmt, "si", $courseName, $isConfirmed); // 循环插入每条数据 foreach ($courses as $row) { $courseName = $row['name'] ?? ''; $isConfirmed = $row['isConfirmed'] ?? 0; mysqli_stmt_execute($stmt); } // 检查插入结果 if (mysqli_stmt_affected_rows($stmt) > 0) { echo json_encode(['status' => 'success', 'message' => "数据保存成功"]); } else { echo json_encode(['status' => 'error', 'message' => "无数据被保存,错误信息: " . mysqli_error($conn)]); } // 关闭语句和数据库连接 mysqli_stmt_close($stmt); mysqli_close($conn); ?>
三、优化React的saveCourses函数(可选)
可以在saveCourses中处理PHP返回的响应,更精准地提示操作结果:
const saveCourses = async () => { const confirmSave = window.confirm("确定要保存数据吗?"); if (confirmSave) { try { const response = await fetch('/api/saveCourses.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(courses) }); const result = await response.json(); if (result.status === 'success') { alert(result.message); } else { alert(`保存失败: ${result.message}`); } } catch (error) { console.error('错误:', error); alert('保存失败: 网络异常'); } } else { alert("保存操作已取消。"); } };
内容的提问来源于stack exchange,提问作者Qoot
相关产品推荐
相关产品推荐

