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

如何用jQuery Ajax实现内容实时逐段加载(每秒新增)效果?

哦,我明白你的问题了——你的PHP脚本是每秒输出一段内容,但用普通的jQuery Ajax调用时,会等所有内容都生成完才一次性显示出来,对吧?这是因为默认的$.ajax的success回调要等到服务器完整返回响应才会触发,没法实时接收逐步输出的内容。

下面我给你两种可行的解决方案,你可以根据自己的需求选择:


方案一:利用XMLHttpRequest的onprogress事件(支持POST请求)

首先,你的PHP脚本需要确保能实时输出并刷新内容,不然服务器会把所有内容攒到一起再发送。调整你的content.php:

<?php
// 关闭输出缓冲,确保内容能实时发送
ob_end_flush();
// 禁用压缩,避免内容被缓冲
ini_set('zlib.output_compression', 0);
// 设置响应头,告诉客户端这是流式文本
header('Content-Type: text/plain; charset=utf-8');
header('Transfer-Encoding: chunked');

// 模拟每秒输出一段内容
for ($i = 0; $i < 5; $i++) {
    echo "第" . ($i + 1) . "段新增内容<br>"; // 用<br>方便页面换行
    flush(); // 立刻把当前输出发送给客户端
    sleep(1); // 等待1秒
}
?>

然后调整你的jQuery代码,我们需要手动创建XMLHttpRequest对象,监听它的progress事件——这个事件会在服务器有新内容返回时触发,而不是等全部完成:

<div class="div"></div>
<script src="//code.jquery.com/jquery.js"></script>
<script>
$(document).ready(function(){
    // 初始化XHR对象
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'content.php', true);
    // 设置POST请求的内容类型
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

    // 监听进度事件:每次有新内容到达时执行
    xhr.addEventListener('progress', function(e) {
        if (e.lengthComputable) {
            // 拿到当前已经显示的内容长度,提取出新增的部分
            const currentContentLen = $('.div').html().length;
            const newContent = this.responseText.substring(currentContentLen);
            // 追加新增内容,而不是替换整个div
            $('.div').append(newContent);
        }
    });

    // 监听请求完成的事件
    xhr.onload = function() {
        console.log('所有内容加载完毕');
    };

    // 发送POST数据
    xhr.send('name=name');
});
</script>

如果你更习惯用jQuery的$.ajax语法,也可以通过xhr选项自定义XHR对象:

<div class="div"></div>
<script src="//code.jquery.com/jquery.js"></script>
<script>
$(document).ready(function(){
    $.ajax({
        url: 'content.php',
        type: 'post',
        data: { name: 'name' },
        // 自定义XHR对象,添加progress监听
        xhr: function() {
            const xhr = new XMLHttpRequest();
            xhr.addEventListener('progress', function(e) {
                if (e.lengthComputable) {
                    const currentLen = $('.div').html().length;
                    const newContent = this.responseText.substring(currentLen);
                    $('.div').append(newContent);
                }
            });
            return xhr;
        },
        success: function() {
            console.log('请求完成');
        }
    });
});
</script>

方案二:使用Server-Sent Events(SSE,更适合实时推送场景)

如果你的请求可以用GET方式,SSE是更优雅的选择——它是HTML5原生支持的服务器推送技术,专门用来处理这种持续的实时内容推送。

先调整content.php为SSE格式:

<?php
// SSE必须设置的响应头
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); // 禁止缓存
header('Connection: keep-alive'); // 保持长连接

ob_end_flush();
flush();

// 模拟每秒推送一条消息
for ($i = 0; $i < 5; $i++) {
    // SSE的消息格式:data: 内容\n\n
    echo "data: 第" . ($i + 1) . "段新增内容<br>\n\n";
    flush();
    sleep(1);
}

// 推送结束信号,让客户端关闭连接
echo "data: __END__\n\n";
flush();
?>

然后客户端代码就非常简洁了:

<div class="div"></div>
<script>
$(document).ready(function(){
    // 创建EventSource,传入PHP脚本地址和GET参数
    const source = new EventSource('content.php?name=name');

    // 监听服务器发送的消息
    source.onmessage = function(e) {
        if (e.data === '__END__') {
            source.close(); // 收到结束信号,关闭连接
            return;
        }
        $('.div').append(e.data);
    };

    // 监听错误(比如连接断开)
    source.onerror = function() {
        console.log('连接关闭或出错');
        source.close();
    };
});
</script>

关键注意点:

  1. PHP端的输出缓冲:一定要关闭输出缓冲并调用flush(),否则服务器会把内容缓存起来,直到脚本执行完才一起发送。
  2. 客户端追加内容:不要用html()替换整个div,要用append()来新增内容,不然每次都会覆盖之前的内容。
  3. SSE的限制:SSE只能用GET请求,如果必须用POST,还是选方案一的XHR方式更合适。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:45:55