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

纯JavaScript实现POST传数据到PHP后用GET获取的问题排查

问题分析与解决方案:POST提交后GET获取数据异常

先梳理下你的问题:用旧的recieve()函数时,POST请求能正常返回"Ok!",也能触发弹窗;但换成新的recieve()后,页面直接刷新,没有任何错误提示,而且还拿不到PHP里POST生成的$var。我帮你拆解下问题点,再给出修正方案。

错误点排查

  1. recieve()里的状态判断错误
    你在新recieve()里写了this.status = 200,这是赋值操作不是比较!应该改成this.status == 200(或者===更严谨),这个错误会导致逻辑异常,甚至可能触发页面刷新。

  2. Promise的then()使用错误
    你当前的代码是send(url, mail).then(recieve(url));,这里recieve(url)会立即执行,而不是等send()的Promise完成后再执行。正确的做法是传递一个回调函数,让它在Promise resolved后再调用。

  3. send()的Promise时机错误
    你现在在req.send(jmail)之后直接resolve("true"),这时候请求可能还没完成,导致then()提前触发,这也是旧函数看起来正常但新函数出问题的原因之一。应该把resolve()放在请求成功回调里(readyState为DONE且status200的时候)。

  4. HTTP无状态导致$var无法跨请求获取
    PHP是无状态的,POST请求生成的$var在请求结束后就消失了,后续的GET请求拿不到这个值。你需要用Session来存储这个变量,让它在同一个会话的不同请求中保持。

修正后的代码

1. JavaScript部分

function send(leURL, laValeur) {
  return new Promise(function(resolve, reject) {
    try {
      var req = new XMLHttpRequest();
      req.open('POST', leURL);
      req.setRequestHeader("Content-Type", "application/json");
      req.onreadystatechange = function() {
        if (this.readyState == XMLHttpRequest.DONE) {
          if (this.status == 200) {
            document.getElementById("result").innerHTML = "Ok!";
            // 请求成功后再resolve,可传递服务器返回的处理结果
            resolve(this.responseText);
          } else {
            // 请求失败时reject,便于捕获错误
            reject(new Error(`请求失败,状态码:${this.status}`));
          }
        }
      };
      // 处理网络请求错误
      req.onerror = function() {
        reject(new Error("网络请求错误"));
      };
      const jmail = JSON.stringify(laValeur);
      req.send(jmail);
    } catch (err) {
      window.alert("erreur 2");
      reject(err);
    }
  });
}

function recieve(laURL) {
  return new Promise(function(resolve, reject) {
    try {
      var reqt = new XMLHttpRequest();
      reqt.open('GET', laURL);
      reqt.onreadystatechange = function(e) {
        if (this.readyState == XMLHttpRequest.DONE) {
          if (this.status === 200) {
            try {
              var rep = JSON.parse(this.responseText);
              window.alert(rep);
              resolve(rep);
            } catch (e) {
              window.alert("erreur 4:解析JSON失败");
              reject(e);
            }
          } else {
            reject(new Error(`GET请求失败,状态码:${this.status}`));
          }
        }
      };
      // 处理GET请求的网络错误
      reqt.onerror = function() {
        reject(new Error("GET网络请求错误"));
      };
      reqt.send();
    } catch (e) {
      window.alert("erreur 3");
      reject(e);
    }
  });
}

// 表单提交事件监听
document.getElementById("form").addEventListener('submit', function(evt) {
  evt.preventDefault();
  // 注意:then里传递回调函数,等待send的Promise完成后再调用recieve
  send(url, mail)
    .then(function() {
      return recieve(url);
    })
    .catch(function(err) {
      // 统一捕获所有Promise链中的错误
      window.alert(`发生错误:${err.message}`);
    });
});

2. PHP部分(加入Session存储)

<?php
// 启动Session,必须在输出任何内容之前调用
session_start();

if (!empty($_POST)) {
  // 处理POST的JSON数据
  $input = json_decode(file_get_contents('php://input'), true);
  // 示例处理逻辑,根据你的实际需求修改
  $var = "处理后的数据:" . $input['mail'];
  
  // 把$var存入Session,供后续GET请求获取
  $_SESSION['saved_var'] = $var;
  
  // 返回处理结果给前端的POST请求
  echo json_encode($var);
} else {
  // GET请求时,从Session取出保存的变量
  if (isset($_SESSION['saved_var'])) {
    echo json_encode($_SESSION['saved_var']);
    // 可选:取出后删除Session变量,避免重复获取
    // unset($_SESSION['saved_var']);
  } else {
    echo json_encode("Hello, there !");
  }
}
?>

关键说明

  • Promise的正确使用:send()要在请求真正完成后才resolve,then()里要传递回调函数,而不是直接执行函数,这样才能保证请求的顺序执行。
  • HTTP无状态特性:如果需要跨请求保存数据,必须用Session、Cookie或者数据库,这里用Session是最简单的会话内数据存储方案。
  • 错误处理:给XMLHttpRequest加上onerror事件,并且在Promise里统一处理reject,这样所有错误都能被catch()捕获,方便排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:16:39