如何使用XMLHttpRequest对象接收流式输入?
如何使用XMLHttpRequest对象接收流式输入?
嘿,我来给你唠唠怎么用XMLHttpRequest(简称XHR)处理流式输入的问题,结合你给出的代码场景来详细说~
首先明确下:流式输入一般指服务器分批次返回数据,客户端不用等所有数据加载完,就能逐步接收并处理的情况,像处理大文件、实时日志推送这类场景都用得到。
一、先修正你当前发送FormData的小问题
看你写的JS代码,用formData.append("field1", ["mockdata1", "mockdata2"])传数组的话,FormData会自动把数组转成逗号分隔的字符串,到PHP那边拿到的就不是数组了。如果要让PHP接收数组,得改成多次append,给键名加上方括号后缀:
let formData = new FormData(); // 多次append,键名加[]表示数组 formData.append("field1[]", "mockdata1"); formData.append("field1[]", "mockdata2"); let xhr = new XMLHttpRequest(); xhr.open("POST", "../phpscripts/agent.php"); xhr.send(formData);
二、用XHR接收服务器的流式响应
如果你的需求是让XHR接收服务器的流式输入(比如PHP分块输出数据),可以利用XHR的onprogress事件来实时接收每一块数据:
1. PHP端(分块输出示例)
先写PHP代码,让它分批次输出数据,模拟流式返回:
// 禁用缓存,确保数据实时返回 header('Cache-Control: no-cache'); // 设置内容类型为文本,方便查看 header('Content-Type: text/plain'); // 分3次输出数据,模拟流式场景 for ($i = 1; $i <= 3; $i++) { echo "这是第{$i}块数据\n"; // 强制输出缓冲区内容,不等待脚本执行完 flush(); ob_flush(); // 模拟延迟,更贴近真实场景 sleep(1); }
2. JS端(XHR流式接收)
修改JS代码,通过onprogress事件实时接收每一块数据:
let xhr = new XMLHttpRequest(); xhr.open("GET", "../phpscripts/agent.php"); // POST请求也适用 // 监听进度事件,服务器每返回一块数据就触发一次 xhr.onprogress = function(event) { if (event.lengthComputable) { console.log(`已接收 ${event.loaded}/${event.total} 字节`); } // 获取当前已接收的部分数据 let partialData = xhr.responseText; console.log("当前接收的内容:", partialData); }; // 监听完成事件,处理最后一块数据 xhr.onload = function() { console.log("所有数据接收完成:", xhr.responseText); }; xhr.send();
三、如果是PHP接收XHR发送的流式数据
要是你的需求反过来,是PHP要接收XHR发送的流式数据(比如上传大文件时的流式处理),可以通过php://input逐块读取:
// 打开输入流 $input = fopen('php://input', 'r'); // 每次读取1024字节,可根据需求调整大小 while ($chunk = fread($input, 1024)) { // 处理每一块数据,比如写入文件或解析内容 echo "收到一块数据:" . $chunk . "\n"; } fclose($input);
这样不管是XHR接收服务器的流式输出,还是PHP接收XHR的流式输入,都能轻松搞定啦~
备注:内容来源于stack exchange,提问作者Abb
相关产品推荐
相关产品推荐

