让ajax更加友好的实现方法(实时显示后台处理进度)

爱哭的小屁孩ok

爱哭的小屁孩ok

2016-02-19 10:41

下面是个简单易学的让ajax更加友好的实现方法(实时显示后台处理进度)教程,图老师小编详细图解介绍包你轻松学会,喜欢的朋友赶紧get起来吧!
ajax应用越来越多,大部分ajax处理都是在前台显示1个"loading...",然后把数据提交给服务器进行处理,处理完毕后显示"处理完毕"。我们能否让ajax更加友好点,实时显示服务器处理的进度了?这在一些长时间的请求中尤其重要,比如上传文件、发送邮件、批量处理数据。答案当然是可以的,不然就不会写这个了,对吧,^_^。

存在的问题:
要解决实现上面的功能,需要解决下面几个问题:

1. 服务器如何在处理一部分数据后传递部分response到浏览器。
2、浏览器如何能处理服务器传递过来部分数据,并保持http连接直到处理完全完毕。

要解决第1个问题,使用flush让response分块进行呈现就可以了,具体请参考我另一遍随笔"flush让页面分块,逐步呈现";
第2个问题,则需要用到XMLHttpRequest的readyState状态,w3c对 readyState 定义如下几个值:
UNSENT = 0; // 没有发送请求
OPENED = 1; // 已经打开http连接
HEADERS_RECEIVED = 2; // 接收到response header
LOADING = 3; // 真正接收response body
DONE = 4; // 请求接收完毕
相信状态4大家是天天在用,而我们这里需要用到就是状态3。
实例:
废话少说,代码实例比什么文字解释都管用。我们这里假设服务器的1个处理需要6秒种,每秒种处理1条记录,总共处理6条记录,我们需要服务器每处理完1条数据,客户端则显示处理进度(包括文字和进度条)。
服务器端代码(下面JSP代码):
代码如下:

%
// 下面设置Content-Type:application/x-javascript 是为了适应Webkit的浏览器(chrome,safari)
response.setHeader("Content-Type","application/x-javascript");
int count = 6; // 处理6条数据
for(int i=0;icount;i++){
// 处理完毕一条,输出结果到客户端
out.println(i+1);
out.flush();
// 这里假设每条数据处理时间为1秒
Thread.currentThread().sleep(1000);
}
%

html代码:
代码如下:

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
html xmlns="http://www.w3.org/1999/xhtml"
head
style
#divProgress{width:300px;height:24px;position:relative;}
#divProgress div{position:absolute;left:0;top:0;height:24px;}
#progressBg{background-color:#B9F8F9;z-index:10;}
#progressText{z-index:15;text-align:center;width:100%;}
/style
/head
body
div id="divProgress"
div id="progressBg"/div
div id="progressText"/div
/div
br /
button onclick="send()"提交数据/button
script
var t = document.getElementById("progressText");
var bg = document.getElementById("progressBg");
function send(){
t.innerHTML = "loading...";
bg.style.width = "0px";
var xhr = new window.XMLHttpRequest();
if(!window.XMLHttpRequest){
try {
xhr = new window.ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {}
}
xhr.open("post","http://localhost:801/ChunkTest/chunk.jsp?count=6");
var oldSize=0;
xhr.onreadystatechange = function(){
if(xhr.readyState 2){
var tmpText = xhr.responseText.substring(oldSize);
oldSize = xhr.responseText.length;
if(tmpText.length 0 ){
// 设置文本
t.innerHTML = tmpText + "/6";
// 设置进度条
var width = parseInt(tmpText)/6*300;
bg.style.width = width+"px";
}
}
if(xhr.readyState == 4){
// 请求执行完毕
t.innerHTML = "执行完毕";
bg.style.width = "300px";
}
}
xhr.send(null);
}
/script
/body
/html

运行效果图: 



缺点:

看到这里或许你已经蠢蠢欲动,想自己动手试试了。但是注意上面的方法虽好,但也有个缺点,就是浏览器的支持问题。目前IE所有版本的浏览器都不支持 xhr.readyState == 3状态,IE浏览器不支持在response响应完毕前读取responseText属性。 具体可查看MSDN : XMLHttpRequest Object

基于Webkit的浏览器支持的不是很好,需要设置Content-Type:application/x-javascript才行(经测试发现Content-Type:text/html在有些情况下正常,有些情况下又不正常,而用application/x-javascript都正常)。

看到了缺点后是否又打击了你的积极性了,其实针对IE,我们不需要做太多处理,IE不支持,就不会显示进度,就变成跟传统的ajax请求一样,一直显示1个loading直到请求完毕。我们只需要加1个简单的判断,判断如果是ie则不执行xhr.readyState 2中的代码,如果不加判断,IE下会报JS错误.

DEMO:

demo服务器不太好,而且在国外,随时可能会点击不了,而且有时候运行效果不是很好,大家知晓下,最好是把代码copy到本地进行测试.
请使用firefox或chrome查看demo,ie查看的效果跟一般的ajax没什么不一样.
http://213.186.44.204:8080/ChunkTest/index.html  
转载请注明出处:http://www.cnblogs.com/BearsTaR/。 禁止商用!
展开更多 50%)
分享

猜你喜欢

让ajax更加友好的实现方法(实时显示后台处理进度)

Web开发
让ajax更加友好的实现方法(实时显示后台处理进度)

图片加载进度实时显示

Web开发
图片加载进度实时显示

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

利用AJAX技术实现网页无刷新进度条显示

Web开发
利用AJAX技术实现网页无刷新进度条显示

AJAX 进度条实现代码

Web开发
AJAX 进度条实现代码

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

jquery ajax执行后台方法

Web开发
jquery ajax执行后台方法

在ASP处理程序时显示进度

ASP
在ASP处理程序时显示进度

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

SQLServer ntile获取每组前10%的数据

SQLServer ntile获取每组前10%的数据

AJAX下的请求方式以及同步异步的区别小结

AJAX下的请求方式以及同步异步的区别小结
下拉加载更多内容 ↓