XMLHttpRequest+PHP表单提交问题:文件与数据无法正常传递
问题分析与解决方案
核心问题1:手动设置multipart/form-data请求头缺少边界标识
当你手动设置xhttp.setRequestHeader("Content-Type", "multipart/form-data")时,必须同时指定boundary参数——这是multipart/form-data格式用来分隔不同表单字段的关键随机标识。浏览器自动提交表单时会自动生成该边界,但手动设置请求头时未添加,PHP无法正确解析请求体,因此出现Missing boundary错误,导致所有表单数据都无法获取。
核心问题2:未正确获取文件对象
不设置请求头时,浏览器会自动添加带正确boundary的multipart/form-data头,但你的JS代码里直接使用pdf_file变量,这个变量并没有指向文件输入框的文件对象,导致FormData中的文件字段为空,PHP自然拿不到$_FILES['pdf_file']数据。
修正后的完整代码
HTML + JavaScript
<body> <form> <input type="text" id="orderID" name="orderID"> <input class="form-control" type="file" name="pdf_file" id="pdf_file"> <input type="button" onclick="saveFiles()" value="send"> </form> <script> function saveFiles() { const orderID = document.getElementById("orderID").value; // 获取文件输入框选中的第一个文件对象 const pdfFile = document.getElementById("pdf_file").files[0]; const xhttp = new XMLHttpRequest(); const formData = new FormData(); formData.append("orderID", orderID); // 确保文件存在时再添加到FormData if (pdfFile) { formData.append("pdf_file", pdfFile); } xhttp.open("POST", "testePHP.php", true); // ❌ 禁止手动设置multipart/form-data请求头,浏览器会自动处理 // xhttp.setRequestHeader("Content-Type", "multipart/form-data"); xhttp.send(formData); xhttp.onreadystatechange = function() { if (xhttp.readyState == 4 && this.status == 200) { alert(xhttp.responseText); } } } </script> </body>
PHP代码
<?php $orderID = $_REQUEST["orderID"] ?? 0; echo "订单ID:" . $orderID . "<br><br>"; // 先判断文件是否存在再访问,避免警告 if (isset($_FILES['pdf_file'])) { echo "文件错误码:" . $_FILES['pdf_file']['error']; // 额外判断是否上传成功 if ($_FILES['pdf_file']['error'] === UPLOAD_ERR_OK) { echo "<br>文件上传成功,文件名:" . $_FILES['pdf_file']['name']; } } else { echo "未收到文件"; } ?>
关键注意事项
- 禁止手动设置
multipart/form-data请求头:通过XMLHttpRequest发送FormData时,浏览器会自动生成包含正确boundary的请求头,手动设置会破坏解析逻辑。 - 正确获取文件对象:必须通过文件输入框的
files[0]属性获取选中的文件,而非直接使用元素ID(元素ID对应的是DOM元素,不是文件对象)。 - PHP端做存在性校验:访问
$_FILES或$_REQUEST前先用isset()检查,避免出现未定义索引的警告。
内容的提问来源于stack exchange,提问作者Libania Paes
相关产品推荐
相关产品推荐

