让ajax更加友好,实时显示后台处理进度。
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代码):
1
2
3
4
5
6
7
8
9
10
11
12
|
<%
// 下面设置Content-Type:application/x-javascript 是为了适应Webkit的浏览器(chrome,safari)
response.setHeader( "Content-Type" , "application/x-javascript" );
int count = 6 ; // 处理6条数据
for ( int i= 0 ;i<count;i++){
// 处理完毕一条,输出结果到客户端
out.println(i+ 1 );
out.flush();
// 这里假设每条数据处理时间为1秒
Thread.currentThread().sleep( 1000 );
}
%>
|
html代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
<! 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
本文转自BearRui(AK-47)博客园博客,原文链接: http://www.cnblogs.com/BearsTaR/archive/2010/06/02/ajax_better_Experience.html ,如需转载请自行联系原作者
让ajax更加友好,实时显示后台处理进度。相关推荐
- android zip解压进度_android zip4j之--解压zip文件并实时显示解压进度
Zip文件是我们经常用到压缩文件格式,android中在进行网络请求大批量数据时,通常会采用传递zip文件,这样做即可以减少网络流量的消耗,加快请求的响应速度,又可以减少对存储空间的要求,所以当我们将 ...
- ajax上传图片成功但不显示,jQuery插件之ajaxFileUpload(异步上传图片并实时显示,并解决onchange后ajaxFileUpload失效问题)...
参考学习: 第一篇:http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html 第二篇:http://www.jb51.net/a ...
- 基于Jquery插件Uploadify实现实时显示进度条上传图片
网址:http://www.jb51.net/article/83811.htm 这篇文章主要介绍了基于Jquery插件Uploadify实现实时显示进度条上传图片的相关资料,感兴趣的小伙伴们可以参考 ...
- 使用Uploadify实现上传图片生成缩略图例子,实时显示进度条
不了解Uploadify的,先看看前一篇详细说明 http://www.cnblogs.com/XuebinDing/archive/2012/04/26/2470995.html Uploadify ...
- jquery+ajax 实现text框模糊搜索并可利用listbox实时显示模糊搜索列表结果
功能描述: text框中输入,text框下面的listbox中实时显示依据输入的内容进行模糊搜索的结果 js代码 1 $j(function() { 2 $j("input[id='txtC ...
- 云优后台提交显示parsererror_微信现场大屏实时显示结果现场投票活动制作方法...
原标题:微信现场大屏实时显示结果现场投票活动制作方法 在文艺晚会上,才艺节目竞赛中,当表演者表演完之后,可能会在现场进行投票表决.因为表演者想要评比出名次,自然需要在现场活动中通过观众或者是评委来进行 ...
- 怎么在html显示已登录状态,jQuery Ajax 实现在html页面实时显示用户登录状态
当网站是全静态的html页面时,而又希望网站会员在登录之后并在所有页面头部显示登录状态,如用户名等,如果未登录就是未登录状态,下面给大家来分享实现的方法. 一.在html静态页面中加入div,并指定I ...
- Java后台日志实时显示
本文仅是一个简单的案例,web端实时显示Java后台日志.需要频繁请求后台以获取日志,并不是长连接. 可以前端传每次想要展示的行数和从第几个字节开始(假设日志文件总共123456字节,但是只想从334 ...
- java 上传 进度,关于 javaweb的文件上传实时显示进度
方法:使用单例保存实时信息.具体的实现方法就是,当用户点击了处理按钮时,在后台开启一个线程进行处理,并且每进行到一步,就向单例中写入当前状态信息.然后编写一个servlet,用于返回单例中的信息,前台 ...
- php显示当前访问人数,PHP与jquery实时显示网站在线人数实例详解
我们在一些应用中需要动态展示数据,比如当前在线人数,当前交易总额,当前汇率等等,前端页面需要实时刷新获取最新数据.本文将结合实例给大家介绍使用jQuery和PHP来实现动态数字展示效果. 本例假设要在 ...
最新文章
- 长连接及在Node中的应用——HTTP/1.1 keep-alive
- Linux配置vsftpd 服务
- hadoop学习-stream-Top K记录
- C++指向成员函数的指针
- C++中dynamic_cast的简介
- android开发技术探索,《android开发艺术探索》读书笔记(十三)--综合技术(示例代码)...
- 动网论坛新手详尽教程
- 【Python】Python3.7.3 - Python内置函数
- psql物化视图自动更新
- 源代码管理分析工具 - Source Navigator
- linkedin第三方授权登录
- oracle分组拼接
- Windows2016 L2TP配置(证书模式)
- B2B网关支付方案介绍
- 知识图谱从入门到应用——知识图谱的知识表示:向量表示方法
- Redis 客户端之Lettuce配置使用(基于Spring Boot 2.x)
- Fiddler+雷电模拟器进行APP抓包
- 简谈Oracle体系结构
- java操作跨页的word cell_Java 操作Word表格——创建嵌套表格、添加/复制表格行或列、设置表格是否禁止跨页断行...
- 用计算机验证克莱姆法则,克莱姆法则的几种证明方法
热门文章
- jfinal_sql注入问题解决
- 通过try、except和else的使用来使Python程序更加“强壮”
- 如何让Win10在开机时跳过锁屏
- ChainOfResponsibilityPattern(23种设计模式之一)
- JForum3 学习笔记1
- 使用vue自定义组件以及动态时间
- 【bzoj 3252】攻略
- [HAOI2006] 聪明的猴子
- 移动端上拉加载下拉刷新插件-mescroll.js插件
- sql函数 StringSplit(SELECT * from Split('黄色,蓝色,黑色',','))