JS Fetch调用PHP REST API出现空值数组偏移错误请求排查
问题:Fetch调用PHP API触发数组偏移访问警告
通过JavaScript的Fetch调用PHP编写的REST API时,收到PHP错误:
Warning error: Trying to access array offset on value of type null php
该API使用SoapUI调用时正常,但通过JavaScript代码调用时触发此错误。
现有代码
JavaScript代码
function compareValueKey(numInput) { let digit_key = document.getElementById("input_compare" + numInput).value; let configFetch = { method: "POST", body: "digit_key=" + digit_key + "&numInput=" + numInput, headers: {'Content-Type': 'application/x-www-form-urleancoded'} }; let promesa = fetch("compareValueKey.php", configFetch); promesa.then(function(response){ if(response.ok){ console.log("Respuesta OK"); } response.json().then( function(objectoJSON){ let valido = objectoJSON.valido; let numInput = objectoJSON.n; document.getElementById("input_compare"+ numInput).nextElementSibling.innerHTML = valido; }); }).catch(function (error){ console.log('Error con la peticion' + error.message); }); }
PHP代码
<?php session_start(); $key =1111; $data = json_decode(file_get_contents('php://input'), true); $digit_key = $data['digit_key']; $numInput = $data['numInput']; if($digit_key == substr($key, $numInput - 1, 1)){ echo json_encode(array("valido" => "ok", "n" => $numInput)); }else{ echo json_encode(array("valido" => "error", "n" => $numInput)); }
HTML代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> <script defer src="actividad06.js" pe="text/javascript"></script> <title>Actividad 6</title> </head> <body class="p-5"> <div id="checkCombination"> <input type="number" id="input_compare1" onkeyup="compareValueKey(1)"><span class="msg"></span> <input type="number" id="input_compare2" onkeyup="compareValueKey(2)"><span class="msg"></span> <input type="number" id="input_compare3" onkeyup="compareValueKey(3)"><span class="msg"></span> <input type="number" id="input_compare4" onkeyup="compareValueKey(4)"><span class="msg"></span> </div> </body> </html>
错误原因
- Content-Type拼写错误:JS中
headers里的Content-Type写成了application/x-www-form-urleancoded,正确应为application/x-www-form-urlencoded(少了字母d),导致PHP无法正确识别请求的表单数据格式。 - 数据解析方式不匹配:PHP代码用
json_decode解析php://input,但JS发送的是表单格式字符串(digit_key=xxx&numInput=xxx),而非JSON格式,因此$data被解析为null,访问$data['digit_key']和$data['numInput']时触发"访问null类型的数组偏移"警告。
修正方案
方案一:修正JS请求头,PHP用$_POST获取数据(推荐,适配当前JS请求格式)
修正后的JavaScript代码
function compareValueKey(numInput) { let digit_key = document.getElementById("input_compare" + numInput).value; let configFetch = { method: "POST", body: "digit_key=" + digit_key + "&numInput=" + numInput, // 修正Content-Type拼写错误 headers: {'Content-Type': 'application/x-www-form-urlencoded'} }; let promesa = fetch("compareValueKey.php", configFetch); promesa.then(function(response){ if(response.ok){ console.log("Respuesta OK"); } response.json().then( function(objectoJSON){ let valido = objectoJSON.valido; let numInput = objectoJSON.n; document.getElementById("input_compare"+ numInput).nextElementSibling.innerHTML = valido; }); }).catch(function (error){ console.log('Error con la peticion' + error.message); }); }
修正后的PHP代码
<?php session_start(); $key =1111; // 改用$_POST获取表单参数,增加空值容错 $digit_key = $_POST['digit_key'] ?? ''; $numInput = $_POST['numInput'] ?? 0; // 增加参数合法性校验,避免非法值导致substr出错 if(is_numeric($numInput) && $numInput >= 1 && $numInput <= 4 && $digit_key == substr($key, $numInput - 1, 1)){ echo json_encode(array("valido" => "ok", "n" => $numInput)); }else{ echo json_encode(array("valido" => "error", "n" => $numInput)); }
方案二:JS发送JSON格式数据,PHP保持json_decode解析
修正后的JavaScript代码
function compareValueKey(numInput) { let digit_key = document.getElementById("input_compare" + numInput).value; let configFetch = { method: "POST", // 将请求体转为JSON字符串 body: JSON.stringify({digit_key, numInput}), // 设置正确的Content-Type headers: {'Content-Type': 'application/json'} }; let promesa = fetch("compareValueKey.php", configFetch); promesa.then(function(response){ if(response.ok){ console.log("Respuesta OK"); } response.json().then( function(objectoJSON){ let valido = objectoJSON.valido; let numInput = objectoJSON.n; document.getElementById("input_compare"+ numInput).nextElementSibling.innerHTML = valido; }); }).catch(function (error){ console.log('Error con la peticion' + error.message); }); }
优化后的PHP代码(增加容错校验)
<?php session_start(); $key =1111; $data = json_decode(file_get_contents('php://input'), true); // 用null合并运算符避免访问null数组 $digit_key = $data['digit_key'] ?? ''; $numInput = $data['numInput'] ?? 0; // 增加参数合法性校验 if(is_numeric($numInput) && $numInput >=1 && $numInput <=4 && $digit_key == substr($key, $numInput - 1, 1)){ echo json_encode(array("valido" => "ok", "n" => $numInput)); }else{ echo json_encode(array("valido" => "error", "n" => $numInput)); }
内容的提问来源于stack exchange,提问作者Pikachuuuu
相关产品推荐
相关产品推荐

