【问题标题】:Showing progress of long-running PHP script using jQuery progressbar使用 jQuery 进度条显示长时间运行的 PHP 脚本的进度
【发布时间】:2017-03-19 15:41:25
【问题描述】:

有时 jQuery 的文档让我觉得自己像个帖子一样愚蠢。

我有一个应用程序在服务器上使用 PHP 来处理多个订单的创建(有时超过一千个)。我试图弄清楚如何让该脚本(通过 $.ajax 调用)通知 UI 其状态。

我了解 $.ajax 中的 .onprogress、.success 和 .complete 元素,但我找不到 PHP 脚本应该如何向每种事件类型提供数据的示例。

在老式 javascript 中,使用 ajax.readyState,您可以从脚本中获取 PHP.echo() 事件以获取进度,然后使用 PHP.exit() 事件来完成请求。

在 $.ajax 世界中如何做到这一点?

非常感谢一只试图学习新技巧的老狗。

【问题讨论】:

    标签: php jquery ajax progress-bar


    【解决方案1】:

    想出一个蛮力的方式。

    每次从服务器端 echo() 时,捆绑包都会作为 e.target.responseText 传递给 onprogress 处理程序。请注意,responseText 会随着每个响应而持续增长,因此您需要一个客户端变量来跟踪其先前的长度:

    var this_str, last_len = 0;
    ...
    onprogress: function (e) {
        this_str = e.target.responseText.substr(last_len);
        ...do something with this_str...
        last_len = e.target.responseText.length;
    }
    ...
    

    如果结果是 json,则需要解码 this_str(不是 responseText)。使用不同的技术效果最好,因为根据服务器更新的频率,您的解析可能会过载。由于您要发送 json 对象,因此整个 responseText 字符串是一系列 json 对象,由右花括号和左花括号“}{”分隔。所以把它分成几部分,并使用最新的:

    var subtext, parts, json;
    ...
    onprogress: function (e) {
        parts = e.target.responseText.split('}{');
        if (parts.length > 1) {
            subtext = '{' + parts[parts.length - 1];
        } else {
            subtext = parts[0];
        }
        json = JSON.parse(subtext);
        ...
    

    success函数对json使用类似的方法:

    success: function (text) {
        parts = text.split('}{');
        if (parts.length > 1) {
            subtext = '{' + parts[parts.length - 1];
        } else {
            subtext = parts[0];
        }
        json = JSON.parse(subtext);
        ...
    

    请注意,随着事情的开始,会有几个无用的 onprogress 事件;一定要测试这些并忽略它们。

    当您的服务器端函数终止或 exit()s 时,您的成功函数和 onprogress 函数都将收到完整的 responseText 字符串。如果您想成功地做一些不同的事情,请记住跟踪 responseText 中的最终字符串。

    【讨论】: