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

PHP服务端脚本执行进度同步至前端JavaScript失效问题求助

解决Ajax实时进度同步失效的问题

我之前也踩过这个坑!你的问题核心是输出缓冲没彻底关闭加上HTTP分块传输没配置正确,导致浏览器把服务端的所有输出攒到一起才返回,根本没法实时触发onprogress。下面给你一步步解决的方案:

1. 彻底关闭服务端的输出缓冲

PHP本身、Web服务器(Apache/Nginx)甚至PHP-FPM都可能有输出缓冲,必须全部关闭才能让内容实时发送给浏览器:

// 在服务端脚本最开头添加这些配置
@ini_set('output_buffering', '0');
@ini_set('implicit_flush', '1');
// 清空所有已存在的输出缓冲
while (ob_get_level()) {
    ob_end_clean();
}
// 禁用Gzip压缩(否则服务器会攒齐内容再压缩发送)
header('Content-Encoding: none');
// 针对Nginx的额外配置,禁用代理缓冲
header('X-Accel-Buffering: no');

2. 启用HTTP分块传输编码

明确告诉浏览器这是分块传输,让它每收到一块内容就触发一次onprogress:

header('Transfer-Encoding: chunked');
header('Content-Type: text/plain; charset=utf-8'); // 用text/plain避免浏览器提前解析不完整的JSON

3. 修正服务端输出格式

每次输出的进度数据要加上分隔符(比如换行),方便前端拆分处理,同时修复你代码里的JSON语法错误:

function Misc_TestComms () {
    // 先加载上面的缓冲关闭和分头配置
    @ini_set('output_buffering', '0');
    @ini_set('implicit_flush', '1');
    while (ob_get_level()) {
        ob_end_clean();
    }
    header('Content-Encoding: none');
    header('X-Accel-Buffering: no');
    header('Transfer-Encoding: chunked');
    header('Content-Type: text/plain; charset=utf-8');

    $runs = 25;
    $i = 0;
    // 发送初始进度,结尾加换行作为分隔符
    echo json_encode(array('progress' => 0, 'count' => $i, 'total' => $runs)) . "\n";
    flush();
    
    while ($i < $runs) {
        $i++;
        sleep(1);
        // 每次输出都加换行
        echo json_encode(array('progress' => (($i/$runs)*100), 'count' => $i, 'total' => $runs)) . "\n";
        flush();
    }
}

4. 优化前端onprogress解析逻辑

原来的代码直接截取字符串可能会拿到不完整的JSON,导致解析错误。我们按换行拆分内容,只处理完整的进度块:

function start () {
    var lastProcessedLine = 0;
    $.ajax({
        url: getAjaxUrl(),
        method: 'POST',
        data: { REQ_TYPE: 'Misc_Action', SUB_TYPE: 'Misc_TestComms' },
        xhrFields: {
            onprogress: function(e) {
                var fullResponse = e.currentTarget.response;
                // 按换行拆分所有已接收的内容
                var lines = fullResponse.split('\n');
                
                // 只处理之前没处理过的完整行(最后一行可能不完整,留到下次)
                for (var i = lastProcessedLine; i < lines.length - 1; i++) {
                    var line = lines[i].trim();
                    if (!line) continue;
                    
                    try {
                        var jsonResponse = JSON.parse(line);
                        document.getElementById('messages').innerHTML = 
                            'Processed '+jsonResponse.count+' of '+jsonResponse.total;
                    } catch (err) {
                        console.error('解析进度数据出错:', err);
                    }
                }
                
                // 更新已处理到的行数
                lastProcessedLine = lines.length - 1;
            }
        },
        success: function(text) {
            console.log('done!');
            document.getElementById('messages').innerHTML = 'Process completed successfully';
        }
    });
}

额外排查点

  • 本地开发环境的特殊情况:Chrome等浏览器在localhost环境下可能会有缓冲优化,即使配置正确也不会实时触发onprogress。可以用curl -v http://你的接口地址测试,看是不是每隔1秒输出一行JSON——如果是,那问题在浏览器,部署到测试服务器就能正常工作。
  • jQuery版本问题:旧版本jQuery对xhrFields的onprogress支持有bug,试试换成原生XMLHttpRequest实现,稳定性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 10:44:06