React Native调用InfinityFree后端API遇400错误求助
问题分析与修复方案
核心问题:请求格式与后端接收方式不匹配
你遇到的400错误,核心原因是前端发送的数据格式和后端期望的接收格式不一致,同时存在请求头、响应头的配置错误,导致后端无法正确解析POST数据,进而返回400错误。
步骤1:修复React Native前端请求代码
错误点:
- 用
JSON.stringify生成JSON字符串,但设置Content-Type: application/x-www-form-urlencoded,后端用$_POST无法解析JSON格式数据 - 前端请求头中设置
Access-Control-Allow-Origin无效,该字段是后端响应头 - async函数混用
.then/.catch,可简化为await写法
修改后的前端代码:
const insertData = async () => { const firstName = 'John'; const lastName = 'Doe'; try { // 直接传递键值对对象,axios会自动转为x-www-form-urlencoded格式 const postData = { firstName, lastName, }; const axiosConfig = { headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Accept': 'application/json' }, cache: false // 禁用缓存,解决间隔报错问题 }; const res = await axios.post('http://mywebsite.great-site.net/insert.php', postData, axiosConfig); console.log("RESPONSE RECEIVED: ", res); } catch (error) { console.error('AXIOS ERROR: ', error); } };
步骤2:修复后端PHP代码
错误点:
- PHP的
header()函数不能传入数组,需逐个设置响应头 - 错误设置响应
Content-Type为application/x-www-form-urlencoded,后端应返回JSON格式 - 未初始化
$response变量,非POST请求时会触发未定义错误 - 缺少请求参数校验,无法明确提示缺失参数的问题
修改后的后端代码:
<?php $host = "sql213.infinityfree.com"; $username = "if0_00000000"; $password = "password"; $database = "if0_34528777_mydatabase"; $conn = new mysqli($host, $username, $password, $database); // 初始化响应数组,避免未定义错误 $response = ["success" => false, "message" => ""]; // 检查数据库连接 if ($conn->connect_error) { $response["message"] = "Connection failed: " . $conn->connect_error; echo json_encode($response); $conn->close(); exit; } // 校验请求方法 if ($_SERVER["REQUEST_METHOD"] === "POST") { // 校验必填参数是否存在 if (!isset($_POST["firstName"]) || !isset($_POST["lastName"])) { $response["message"] = "Missing required parameters: firstName/lastName"; echo json_encode($response); $conn->close(); exit; } $Acc_FirstName = $_POST["firstName"]; $Acc_LastName = $_POST["lastName"]; // 准备预编译SQL语句,防止注入 $sql = "INSERT INTO `user`(`Acc_FirstName`, `Acc_LastName`) VALUES (?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("ss", $Acc_FirstName, $Acc_LastName); if ($stmt->execute()) { $response["success"] = true; $response["message"] = "Data inserted successfully"; } else { $response["message"] = "Failed to insert data: " . $conn->error; } $stmt->close(); } else { $response["message"] = "Invalid request method: only POST allowed"; } // 设置正确的响应头 header("Content-Type: application/json"); header("Access-Control-Allow-Origin: *"); // 返回JSON响应 echo json_encode($response); $conn->close(); ?>
步骤3:解决“每隔一次点击报错”的问题
该现象大概率是错误请求导致的缓存或重复请求问题,修复上述格式问题+前端添加cache: false配置后即可解决。如果仍存在,可给按钮添加防抖逻辑,避免短时间内重复触发请求:
// 防抖函数 const debounce = (func, delay) => { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; }; // 包裹insertData const debouncedInsert = debounce(insertData, 500); // 按钮点击调用debouncedInsert
额外建议
- 先通过Postman/curl测试后端API,直接传递
firstName和lastName参数,验证后端是否正常工作 - InfinityFree支持免费SSL,建议切换到HTTPS请求,避免明文传输数据
- 可在后端添加错误日志记录,方便排查复杂问题
内容的提问来源于stack exchange,提问作者kim
相关产品推荐
相关产品推荐

