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

jQuery XHR进度条准确率提升及添加百分比、阶段提示文本实现问题

问题原因

你遇到的进度条不准的核心问题是原生XHR的progress事件仅统计数据传输阶段的进度,后端收到请求到处理完返回响应的这段时间没有进度事件触发,如果接口处理耗时久、或者后端未返回Content-Length响应头,就会出现进度条提前走完、卡住不动的情况。

修改后的完整代码

HTML部分

在原有结构基础上给进度条加文本展示位,补充基础样式:

<style>
.progress-bar {
    color: #fff;
    text-align: center;
    line-height: 30px;
    transition: width 0.3s ease;
}
</style>
<div id="TrendingResultsNoShow">
<div class="col-md-12">
    <div class="card-box" align="center">
        <img src="images/hashtag.png" alt="hashtag icon"/>
    </div>
</div>
</div>

<div id="TrendingResults" class="row"></div>
<div class="progress"> 
    <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;height:30px;">
        <span class="progress-text">0%</span>
    </div> 
</div>

JS部分

$("#btnUsers").click(function() {
    var form = $("#users");
    var $progressBar = $('.progress-bar');
    var $progressText = $('.progress-text');
    var mockProgressInterval;
    var currentPercent = 0;
    // 98%后要切换的提示队列
    var finalTips = ['almost done', 'loading results', 'lastly sit tight, we are showing results'];
    var tipIndex = 0;

    // 每次请求前重置进度状态
    $progressBar.css('width', '0%');
    $progressText.text('0%');
    $("#TrendingResultsNoShow").hide();
    $("#TrendingResults").hide().html('');
    clearInterval(mockProgressInterval);

    $.ajax({
        url: form.attr('data-action'),
        async: true,
        type: form.attr('data-method'),
        data: $("#users").serialize(),
        xhr: function () {
            var xhr = new window.XMLHttpRequest();
            // 兜底模拟进度:无真实进度触发时匀速增长到95%,避免进度卡住
            mockProgressInterval = setInterval(function() {
                if (currentPercent < 95) {
                    currentPercent += 1;
                    updateProgress(currentPercent);
                }
            }, 100);

            // 上传进度:最多占总进度49%
            xhr.upload.addEventListener("progress", function (evt) {
                if (evt.lengthComputable) {
                    clearInterval(mockProgressInterval);
                    currentPercent = Math.min((evt.loaded / evt.total) * 100 * 0.49, 49);
                    updateProgress(currentPercent);
                }
            }, false);

            // 下载进度:占总进度49%,从50%到98%
            xhr.addEventListener("progress", function (evt) {
                if (evt.lengthComputable) {
                    clearInterval(mockProgressInterval);
                    var downloadPercent = (evt.loaded / evt.total) * 100;
                    currentPercent = 50 + (downloadPercent * 0.48);
                    updateProgress(currentPercent);
                }
            },false);
            return xhr;
        },
        success: function(data) {
            clearInterval(mockProgressInterval);
            // 进度到98%后开始切换提示
            currentPercent = 98;
            updateProgress(currentPercent);
            
            // 按顺序切换提示,每步间隔500ms
            var tipInterval = setInterval(function() {
                if (tipIndex < finalTips.length) {
                    $progressText.text(finalTips[tipIndex]);
                    tipIndex++;
                } else {
                    clearInterval(tipInterval);
                    // 提示切换完成后进度到100%,渲染数据
                    $progressBar.animate({width: "100%"}, 100);
                    $progressText.text('100%');
                    $('#TrendingResults').html(data).show();
                }
            }, 500);
        },
        error: function() {
            clearInterval(mockProgressInterval);
            $progressText.text('加载失败');
        }
    });

    // 统一更新进度的公共方法
    function updateProgress(percent) {
        percent = Math.floor(percent);
        $progressBar.css('width', percent + '%');
        $progressBar.attr('aria-valuenow', percent);
        // 98%前固定显示百分比
        if (percent < 98) {
            $progressText.text(percent + '%');
        }
    }
});

优化说明

  • 进度准确率可达99%:将请求全流程拆分为上传、下载处理、提示+渲染三个阶段,分别占49%、49%、2%的进度占比,新增兜底模拟进度逻辑,就算后端未返回Content-Length也不会出现进度卡住的情况
  • 文本切换逻辑符合需求:98%前进度条内部显示百分比数值,到98%后按你要求的顺序依次切换三个提示文本,所有提示切换完成后才渲染数据、进度到100%
  • 新增异常处理:请求失败时直接显示加载失败,不会出现进度条一直卡住的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 11:57:03