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

多请求场景下Ajax状态Pending问题:jQuery进度监听器实现故障修复问询

问题根源

  • 核心原因是PHP默认的会话锁定机制:当同一个用户的多个请求同时到达时,PHP会给第一个请求(也就是script.php)加上session文件锁,后续所有同用户的请求(包括所有checkprogress.php请求)都会进入排队状态,直到script.php执行完成释放锁,所以才会出现所有进度查询请求都pending到最后才一次性返回的情况。
  • 次要原因可能是文件权限不足、服务端输出缓冲未关闭导致进度值不能及时返回。

修复方案

步骤1:修改两个业务脚本,关闭会话锁和输出缓冲

修改后的checkprogress.php

<?php
// 关闭会话锁,释放请求阻塞
session_write_close();
// 关闭PHP自带输出缓冲
if (ob_get_level()) ob_end_clean();
// Nginx环境可选加下一行,关闭代理缓冲
// header('X-Accel-Buffering: no');

$file = "progress.txt";
// 兼容文件不存在的场景,默认返回0
if (!file_exists($file)) {
    echo 0;
} else {
    $data = file_get_contents($file);
    echo $data;
}
exit;
?>

修改后的script.php

<?php
// 同样关闭会话锁,避免阻塞后续进度查询请求
session_write_close();

$file = "progress.txt";
// 初始化进度为0
file_put_contents($file, 0);

for($i = 1; $i<= 10; $i++){
    sleep(1);
    file_put_contents($file, ($i * 10));
}
echo "执行完成";
// 任务执行完成后可选删除进度文件
// unlink($file);
?>

步骤2:确认目录权限

确保脚本运行目录有可写权限,保证script.php可以正常创建、写入progress.txt文件,Linux环境下可以临时给当前目录设置755权限测试。

步骤3:可选优化前端代码(非必须,避免全局变量污染)

给xhr、timer、xhr2变量加上let声明,避免变成全局变量引发异常:

function begin(event){
    let xhr = new XMLHttpRequest();
    let timer;
    // 其余原有逻辑保持不变
}

function checkProgress(event){
    let xhr2 = new XMLHttpRequest();
    // 其余原有逻辑保持不变
}

验证效果

修改完成后重启PHP服务,清空浏览器缓存重新测试,即可看到进度条每秒上涨10%,10秒后弹出执行完成提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:45:02