You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:35:58