前面几位大神说的都对,但是题主的要求Ajax是无法实现的。
Ajax都是一次请求结束了,调用一个回调来通知
实时的获取数据的动态变化做不到
感谢 @白一梓 让我知道了XMLHttpRequest level 2 API(对以上言辞做修改),于是有了第4种方法
提供几种方法:
用EventSource(这个个个浏览器的支持不一,IE就不支持)看这两个就能看懂MDN EventSource,这里面有个例子
WebSocket
内嵌一个隐藏的iframe,iframe的src属性指向你的长耗时任务的URL,然后写一个Timer不停的去刷新iframe中的内容,根据内容字符串的最后一个百分号的值,获得进度。
使用ajax XMLHttpRequest level 2 API
PS: 另外CGI的机制不太清楚,是CGI执行完毕,一次性的获得stdout的内容,一次性传回,还是一边执行CGI一边传输stdout的输出,如果是前置,那就没办法了
这里把方法4做个例子:
服务器端用nodejs写一个模拟(Node.js >= v4.x)
'use strict';
const http = require('http');
const server = http.createServer();
server.on('request', function(req, res) {
console.log('HTTP', req.method, req.url);
let n = 0;
res.writeHead(200, {
'Content-Type': 'text/plain',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*',
'Content-Length': 100
});
const inter = setInterval(function() {
res.write('.');
n++;
if (n >= 100) {
clearInterval(inter);
res.end();
}
}, 50);
res.on('error', function(err) {
console.log(err);
});
res.on('close', function() {
console.log('Connection close');
})
});
server.listen(8000);
网页如下:
.progress-bar {
border: 1px solid rgb(230, 230, 230);
padding: 0px;
position: relative;
height: 4px;
border-radius: 2px;
}
.progress-bar > .progress-bar-inner {
margin: 0px;
width: 30%;
background-color: rgb(0, 180, 20);
height: 4px;
border-radius: 2px;
}
var progress = $('#pro');
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8000/', true);
xhr.onprogress = function(event) {
if (event.lengthComputable) {
var pro = event.loaded/event.total;
console.log(pro);
progress.css('width', pro*100 + '%');
}
};
xhr.send();