React Native条码扫描后POST数据到PHP API失败问题求解
React Native扫码提交PHP接口故障排查与修正方案
前端scanner.js常见问题与修正
以下是扫码提交逻辑里新手最容易踩的坑,对应修正即可:
- 提交请求未设置正确请求头:
fetch默认发送的文本格式请求,PHP无法自动解析JSON格式的请求体,必须手动指定Content-Type: application/json - 闭包陷阱:扫码回调里拿到的条码值如果存在组件state里,提交时如果没有正确依赖state值,容易拿到初始空值
- 未捕获请求异常:网络错误、权限拦截(安卓明文HTTP请求拦截)的报错被直接吞掉,看不到具体失败原因
- 重复触发提交:扫码成功后没有立即暂停扫码,导致回调多次触发,重复提交冲掉正常请求
修正后的Register提交函数参考
// 配置接口地址,注意如果是HTTP接口要先配置明文权限 const API_URL = "http://你的接口地址/submit.php"; const Register = async (barcodeValue) => { // 先校验拿到的条码值是否有效 if (!barcodeValue) { Alert.alert("提交失败", "条码值为空"); return; } try { const response = await fetch(API_URL, { method: "POST", headers: { "Content-Type": "application/json", // 必须加这个头,PHP才能识别JSON传参 }, body: JSON.stringify({ barcode: barcodeValue, // 字段名和后端约定一致 }), }); const result = await response.json(); if (result.code === 0) { Alert.alert("提交成功", result.msg); // 提交成功后再做页面跳转/重置扫码状态 } else { Alert.alert("提交失败", result.msg || "服务端返回错误"); } } catch (err) { // 打印错误方便排查 console.log("提交报错:", err); Alert.alert("提交失败", "网络请求异常,请检查接口地址和网络权限"); } }; // 扫码回调示例 const handleBarCodeScanned = ({ type, data }) => { setScanned(true); // 立即暂停扫码,避免重复触发 Register(data); // 直接把扫码拿到的data传给提交函数,避免闭包拿不到最新state };
注意:如果你的接口是HTTP非HTTPS地址,Expo项目需要在
app.json里添加配置允许明文请求:{ "expo": { "android": { "usesCleartextTraffic": true } } }
后端PHP接口常见问题与修正
- 取参方式错误:不能用
$_POST获取JSON格式的POST数据,必须读取原始请求流解析 - 缺少CORS跨域头:移动端请求跨域会被直接拦截,拿不到响应
- 响应格式错误:没设置JSON响应头,前端解析返回值失败
- 没有错误捕获:数据库连接、插入失败时直接返回空,无法定位问题
修正后的PHP接口参考
<?php // 允许跨域,正式环境可以把*替换成你的应用对应访问规则 header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: POST, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type"); header("Content-Type: application/json; charset=utf-8"); // 处理OPTIONS预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; } // 初始化返回结构 $response = ['code' => 1, 'msg' => '未知错误']; try { // 正确获取JSON格式的POST数据 $rawPost = file_get_contents('php://input'); $postData = json_decode($rawPost, true); if (!isset($postData['barcode']) || empty(trim($postData['barcode']))) { throw new Exception("条码参数不能为空"); } $barcode = trim($postData['barcode']); // 数据库连接 替换为你自己的库配置 $pdo = new PDO( 'mysql:host=localhost;dbname=你的库名;charset=utf8mb4', '数据库账号', '数据库密码', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); // 用PDO预处理插入,避免SQL注入 $stmt = $pdo->prepare("INSERT INTO member (barcode, create_time) VALUES (:barcode, NOW())"); $stmt->execute([':barcode' => $barcode]); $response['code'] = 0; $response['msg'] = "提交成功,插入ID:" . $pdo->lastInsertId(); } catch (Exception $e) { $response['code'] = 1; $response['msg'] = "错误:" . $e->getMessage(); } // 返回JSON响应 echo json_encode($response, JSON_UNESCAPED_UNICODE); exit; ?>
排查顺序建议
- 先用Postman等接口工具直接请求PHP接口,传JSON格式的barcode参数,确认接口能正常插入数据、返回正确响应,先排除后端问题
- 前端提交时加console.log打印拿到的条码值、请求错误信息,确认值正确、请求能正常发出
- 如果还是失败,抓包查看请求实际发送的地址、请求头、请求体是否和预期一致
内容的提问来源于stack exchange,提问作者jj.
相关产品推荐
相关产品推荐

