这是可能的,通过轮询。棘手的部分将是协调服务器端多个用户的过程。我将在下面解释工作流程。
方法
/**
* 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>"