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

使用Fetch API与XHR同步POST传JS变量至PHP时$_POST为空的问题

问题

我正在本地WordPress站点开发功能,需求是用户提交表单数据后,由PHP处理修改并实现无刷新展示结果。尝试了JavaScript的fetch()和XHR两种异步POST方法,点击提交按钮后虽能成功请求到PHP文件,但print_r($_POST)始终返回空数组。试过传递FormData对象、JSON字符串、普通字符串,均无法将变量传入PHP的POST变量中。另外,不解为何PHP脚本中的echo内容无法显示在页面上,希望得到原因解释和解决帮助。

相关代码如下:

HTML代码

<html>
<div>
<section>
<form id="testForm"  action="file.php" method="post">
<input type="text" id="testInput" name="testInput">
<input type="button" id="testBtn" name="testBtn" value="Test Button">
</form>
</section>
</div>
</html>

JavaScript代码

let testButton = document.getElementById("testBtn");
let tef = document.getElementById("testForm");
var variableValue = tef.value;
var formData = new FormData(tef);
var xhr = new XMLHttpRequest();

xhr.open("POST", "/file.php", true);
xhr.open("GET", "/file.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
    if (xhr.status === 200) {
        console.log(xhr.responseText);
    } else {
        console.error("Error:", xhr.status);
    }
}
};


testButton.onclick = function(){
    testButton.style.color = "red"; // confirm click

    fetch("/file.php", {
        method: "POST",
        body: JSON.stringify({'testForm':variableValue})
    })
    .then(res => res.text())
    .then(txt => {
        alert(txt);
    })
    .catch(e => console.error(e));

    xhr.send(formData);
    xhr.onload = function(){
    testButton.style.color = "purple"; // initial confirmation XHR method has worked
    };
    }

PHP代码

<?php

echo "This works!"; //this is visible in alert or console but never the page

print_r($_POST); // always returns an empty array so far

?>

问题分析与解决方法

一、$_POST为空的原因及修复

  • XHR请求的致命错误:重复调用open()方法
    你先后调用了xhr.open("POST", ...)和xhr.open("GET", ...),第二次调用会完全覆盖第一次的请求配置,最终XHR发送的是GET请求,自然不会有POST数据。删除多余的xhr.open("GET", "/file.php", true);即可。

  • FormData初始化时机错误
    页面加载时就创建formData,此时输入框还没有用户输入的内容,所以FormData是空的。需要把FormData的创建移到按钮点击事件内部,确保获取到最新的表单数据:

    testButton.onclick = function(){
        // ...其他代码
        var formData = new FormData(tef); // 移到点击事件内
        xhr.send(formData);
        // ...其他代码
    }
    
  • Fetch的JSON数据未被PHP解析
    用JSON.stringify()发送数据时,PHP默认不会自动将其解析到$_POST中(因为默认Content-Type不是application/x-www-form-urlencoded)。有两种解决方式:

    1. 改用FormData发送Fetch请求:
      fetch("/file.php", {
          method: "POST",
          body: new FormData(tef)
      })
      
    2. 在PHP中手动解析JSON:
      $jsonData = json_decode(file_get_contents('php://input'), true);
      print_r($jsonData); // 可获取到JSON格式的请求数据
      
  • 表单值获取错误
    tef.value是表单元素本身的value属性,而非输入框的内容。要获取输入框的值,应该用document.getElementById("testInput").value。

二、PHP的echo内容无法显示在页面上的原因

你使用的是异步请求(fetch/XHR),这类请求是在后台静默发送的,服务器返回的响应只会回到JS的回调函数里(比如fetch的then、XHR的onreadystatechange),不会自动替换页面内容。如果要把结果显示在页面上,需要手动操作DOM:

// 先在HTML中添加结果展示容器:<div id="result"></div>

// Fetch回调中更新页面
.then(txt => {
    document.getElementById("result").innerHTML = txt;
})

// XHR回调中更新页面
if (xhr.status === 200) {
    document.getElementById("result").innerHTML = xhr.responseText;
}

三、修复后的完整示例代码

调整后的JavaScript

let testButton = document.getElementById("testBtn");
let tef = document.getElementById("testForm");
let resultContainer = document.getElementById("result");
var xhr = new XMLHttpRequest();

// 仅配置一次POST请求
xhr.open("POST", "/file.php", true);
// 发送FormData时无需手动设置Content-Type,浏览器会自动处理
xhr.onreadystatechange = function () {
    if (xhr.readyState === XMLHttpRequest.DONE) {
        if (xhr.status === 200) {
            resultContainer.innerHTML = xhr.responseText;
            console.log(xhr.responseText);
        } else {
            console.error("Error:", xhr.status);
        }
    }
};

testButton.onclick = function(){
    testButton.style.color = "red";

    // 方案1:用Fetch发送FormData
    fetch("/file.php", {
        method: "POST",
        body: new FormData(tef)
    })
    .then(res => res.text())
    .then(txt => {
        alert(txt);
        resultContainer.innerHTML = txt;
    })
    .catch(e => console.error(e));

    // 方案2:用XHR发送FormData(测试时建议注释掉其中一种请求)
    // let formData = new FormData(tef);
    // xhr.send(formData);
    // xhr.onload = function(){
    //     testButton.style.color = "purple";
    // };
}

调整后的PHP

<?php
echo "This works!<br>";
// 处理FormData提交的情况
print_r($_POST);

// 如果需要处理JSON提交,保留以下代码
// $jsonData = json_decode(file_get_contents('php://input'), true);
// echo "<br>JSON数据:<br>";
// print_r($jsonData);
?>

补充结果容器的HTML

<html>
<div>
<section>
<form id="testForm"  action="file.php" method="post">
<input type="text" id="testInput" name="testInput">
<input type="button" id="testBtn" name="testBtn" value="Test Button">
</form>
<!-- 新增结果展示容器 -->
<div id="result"></div>
</section>
</div>
</html>

内容的提问来源于stack exchange,提问作者First Last

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 04:43:13