PHP XHR请求本地正常服务器异常,排查IIS/PHP配置问题
进度条本地正常、服务器部署后仅执行完毕响应的排查与解决
我在实现脚本执行进度条功能时,本地Visual Studio测试完全正常,但部署到服务器后进度条失效——只有等脚本全部执行完成才会触发响应。试过多种XHR实现方式(包括xhrFields、原生XHR),均是本地正常、服务器异常。请问是否存在PHP或IIS配置项导致该问题?
我的代码
PHP 文件
if ($_SERVER['REQUEST_METHOD'] == 'POST') { header('Content-Type: application/json'); $response = array(); $links = array(); $progress = 0; $progressFinal = 10; echo json_encode(array('progress' => $progress)); ob_implicit_flush(true); ob_end_flush(); for($i = 0; $i < 10; $i++) { sleep(2); $progress++; echo json_encode(array('progress' => (round(($progress / $progressFinal) * 100)))); flush(); ob_flush(); } }
JS 文件
$.ajax({ url: "test.php", type: 'POST', dataType: 'json', async: true, xhrFields: { onprogress: function (e) { var thisResponse, response = e.currentTarget.response; if (lastResponseLen === false) { thisResponse = response; lastResponseLen = response.length; } else { thisResponse = response.substring(lastResponseLen); lastResponseLen = response.length; } jsonResponse = JSON.parse(thisResponse); $('#emrcp').html('- ' + jsonResponse.progress + '%'); } }, success: function (text) { $('#emrcBtn').html('Sent!'); for (var i = 0; i < response.links.length; i++) { $('#emlStat' + response.links[i].fam_id).html('Sent...'); } } });
可能的PHP配置问题
- 输出缓冲:检查
php.ini中的output_buffering配置,若设为On或具体数值(如4096),输出会被缓冲直到缓冲区满才发送。需将其设为Off,或在脚本开头添加ini_set('output_buffering', 'Off');强制关闭。 - zlib压缩:若开启
zlib.output_compression,压缩机制会缓冲输出,必须关闭该配置,或在脚本中添加ini_set('zlib.output_compression', 0);。 - 缓冲清理顺序:确保在输出前先清空现有缓冲,再开启隐式刷新。可调整PHP代码开头:
ob_end_clean(); // 先清空并关闭现有输出缓冲 ob_implicit_flush(true); // 开启自动刷新
可能的IIS配置问题
- 动态内容压缩:IIS的动态内容压缩会缓冲PHP输出,需关闭该功能:
- 打开站点的「压缩」设置
- 取消勾选「启用动态内容压缩」
- FastCGI缓冲设置:IIS的FastCGI默认会缓冲输出,需调整配置:
- 打开IIS管理器的「FastCGI设置」
- 找到对应PHP的条目,右键选择「编辑」
- 在「环境变量」中添加
PHP_FCGI_MAX_REQUESTS(按需设置数值),同时确保输出缓冲被禁用
- 应用程序池配置:检查应用程序池的「高级设置」,确保未启用与输出缓冲相关的选项。
代码优化建议
- JSON输出分隔:每次输出JSON后添加换行符,避免前端解析多个连续JSON时出错:
echo json_encode(array('progress' => $progress)) . "\n"; - 前端变量初始化:
lastResponseLen需提前初始化,避免未定义报错:var lastResponseLen = false; $.ajax({ // 现有配置 });
内容的提问来源于stack exchange,提问作者CaptainJackSparrow
相关产品推荐
相关产品推荐

