PHP无法获取jQuery Ajax PUT请求提交的FormData表单数据
问题根因
- 核心错误:
parse_str()仅支持解析application/x-www-form-urlencoded格式的请求体,当前端通过FormData传参时,请求Content-Type为multipart/form-data,请求内容是带WebKitFormBoundary分隔符的分段格式,parse_str()无法识别这种结构,会把整段请求内容识别为单个键名,自然无法读取id等字段值。 - 额外隐藏bug:
GET分支漏写break,会导致GET请求执行完getGebruiker()后继续向下执行createGebruiker()逻辑。 - POST请求能正常运行是因为PHP原生会自动解析
multipart/form-data格式的POST请求,将数据写入$_POST全局变量,但PHP不会对PUT、DELETE请求做这类自动解析。DELETE请求之前能正常运行,大概率是因为传DELETE请求时用的不是FormData,而是urlencoded格式参数,可以被parse_str()正常识别。
修复方案
二选一即可,根据业务场景选择:
方案1:后端增加multipart格式PUT请求解析(推荐,兼容现有前端逻辑、支持文件上传)
替换PUT分支原有解析逻辑,同时补上GET分支缺失的break:
$requestMethod = $_SERVER['REQUEST_METHOD']; switch ($requestMethod) { case "GET": getGebruiker(); break; // 补全缺失的break case "POST": createGebruiker(); break; case "PUT": $rawInput = file_get_contents('php://input'); $contentType = $_SERVER['CONTENT_TYPE'] ?? ''; $_PUT = []; // 识别multipart/form-data格式 if (strpos($contentType, 'multipart/form-data') === 0) { preg_match('/boundary=(.*)$/', $contentType, $boundaryMatch); $boundary = $boundaryMatch[1] ?? ''; if ($boundary) { $blocks = explode("--" . $boundary, $rawInput); foreach ($blocks as $block) { $block = trim($block); if (empty($block) || $block === '--') continue; // 拆分字段头和字段值 [$header, $value] = explode("\r\n\r\n", $block, 2); $value = rtrim($value, "\r\n"); // 提取字段名 if (preg_match('/name="([^"]+)"/', $header, $nameMatch)) { $_PUT[$nameMatch[1]] = $value; } } } } else { // 兼容x-www-form-urlencoded格式 parse_str($rawInput, $_PUT); } print_r($_PUT); echo $_PUT['id']; updateGebruiker(); break; case "DELETE": parse_str(file_get_contents("php://input"), $_DELETE); deleteGebruiker(); break; default: exit(); }
方案2:前端改传urlencoded格式参数(仅适合无文件上传的表单)
如果表单不需要上传文件,可以去掉FormData,直接序列化表单为urlencoded格式,后端原有解析逻辑不需要修改:
$('#bewerkGebruikerForm').on('submit', function(event) { event.preventDefault(); // 直接序列化表单为urlencoded格式 const formData = $(this).serialize(); $.ajax({ url: 'http://localhost/P08/hoornhek/api/gebruiker.php', type: 'put', data: formData, dataType: 'json', success: function(response) { if(response['success']) { $('#bewerkGebruikerModal').hide(); window.location.reload(); } else { showErrors(response.errors); } }, error: function(error) { showErrors(error.errors); } }); });
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

