纯JavaScript实现POST传数据到PHP后用GET获取的问题排查
问题分析与解决方案:POST提交后GET获取数据异常
先梳理下你的问题:用旧的recieve()函数时,POST请求能正常返回"Ok!",也能触发弹窗;但换成新的recieve()后,页面直接刷新,没有任何错误提示,而且还拿不到PHP里POST生成的$var。我帮你拆解下问题点,再给出修正方案。
错误点排查
recieve()里的状态判断错误
你在新recieve()里写了this.status = 200,这是赋值操作不是比较!应该改成this.status == 200(或者===更严谨),这个错误会导致逻辑异常,甚至可能触发页面刷新。Promise的
then()使用错误
你当前的代码是send(url, mail).then(recieve(url));,这里recieve(url)会立即执行,而不是等send()的Promise完成后再执行。正确的做法是传递一个回调函数,让它在Promise resolved后再调用。send()的Promise时机错误
你现在在req.send(jmail)之后直接resolve("true"),这时候请求可能还没完成,导致then()提前触发,这也是旧函数看起来正常但新函数出问题的原因之一。应该把resolve()放在请求成功回调里(readyState为DONE且status200的时候)。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
相关产品推荐
相关产品推荐

