2

我想在网页上显示数据,假设我在服务器上有一个跟踪器,可能需要很长时间,但我想显示数据。

如果我这样做:

 $.ajax({
         url: '/cgi-bin/trace.cgi',
         dataType: 'text',
         async: true,
         cache: false,
         success: function (response) {
           $('#traceOut').append(response);
         }
        });

只有当我们完成 cgi 请求时才会调用它。

我可以直接使用 XMLHttpRequest、onreadystatechange 和 xmlhttp.readyState==3 来完成这在 Firefox 中可以正常工作,但在 Chrome 中它只会在达到 2k 时转储数据。

我如何在 jQuery 中做到这一点?

4

1 回答 1

0

这是可能的,通过轮询。棘手的部分将是协调服务器端多个用户的过程。我将在下面解释工作流程。

方法

/**
 * Polls a URL until server indicates task is complete,
 * then sends a final request for those results.
 * 
 * Requires jQuery 1.4+.
 */
function poll(params) {

    // offer default params
    params = $.extend({
        error: function(xhr, status, err) {
            console.log('Network error: ' + status + ', ' + err);
        },
        progress: function(prog) {
            console.log(prog);
        },
        timeoutMillis: 600000,    // 10 minutes
        intervalMillis: 3000      // 3 seconds
    }, params);

    // kickoff
    _poll(params);

    function _poll(params) {
        $.ajax({
            url: params.url,
            type: 'GET',
            dataType: 'json',
            timeout: params.timeoutMillis,
            data: 'action=poll',
            success: (function(response, status, xhr) {
                if ('progress' in response) {
                    params.progress('Progress: ' + response.progress);
                }
                if ('status' in response) {
                    if (response.status == 'pending') {
                        // slight delay, then poll again
                        // (non-recursive!)
                        setTimeout((function() {
                            _poll(params);
                        }), params.intervalMillis);
                    }
                    else if (response.status == 'cancelled') {
                        params.progress("Task was cancelled");
                    }
                    else {
                        params.progress("Task complete");
                        // done polling; get the results
                        $.ajax({
                            url: params.url,
                            type: 'GET',
                            timeout: params.timeoutMillis,
                            data: 'action=results',
                            success: params.success,
                            error: params.error
                        });
                    }
                }
            }),
            error: params.error
        });
    }
}

示例用法

poll({
    url: '/cgi-bin/trace.cgi',
    progress: function(prog) {
        $('body #progress').text(prog);
    },
    success: function(response, status, xhr) {
        $('body').html(response);
    }
});

工作流程

此方法将向服务器发送请求,参数“action”设置为“poll”。CGI 脚本应该启动它的后台任务,在用户会话中保持一些状态,并使用 JSON 格式的字符串进行响应:

{"status": "pending", "progress": "0%"}

浏览器将重复发出这些“action=poll”请求,直到响应指示完成。CGI 脚本必须跟踪任务的进度并相应地响应浏览器。这将涉及会话处理和并发:

{"status": "pending", "progress": "25%"}
{"status": "pending", "progress": "50%"}
{"status": "pending", "progress": "75%"}
{"status": "complete"}

然后浏览器将发出“action=results”请求以接收后台任务的最终有效负载。在这个例子中,它只是 HTML:

"<p>The answer is: 42</p>"
于 2012-09-05T07:25:03.327 回答