让ajax更加友好,实时显示后台处理进度。
2010-06-02 08:49
429 查看
ajax应用越来越多,大部分ajax处理都是在前台显示1个"loading...",然后把数据提交给服务器进行处理,处理完毕后显示"处理完毕"。
我们能否让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代码):
运行效果图:
缺点:
看到这里或许你已经蠢蠢欲动,想自己动手试试了。但是注意上面的方法虽好,但也有个缺点,就是浏览器的支持问题。目前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
我们能否让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代码):
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
相关文章推荐
- 让ajax更加友好,实时显示后台处理进度。
- 让ajax更加友好,实时显示后台处理进度。
- 让ajax更加友好的实现方法(实时显示后台处理进度。)
- jsp实时显示后台批处理进度 - out分块,简单的长连接方式
- 使用重写的$.ajax()实现后台处理进度显示(gif)
- 利用Ajax生成ProgressBar:实现同类大批量数据批量生成Html,并实时显示进度条,可查看处理日志
- 通过Handler实现先显示进度条,后台进行数据处理,处理结束后取消进度条
- jQuery progressbar通过Ajax请求实现后台进度实时功能
- Python显示进度条,实时显示处理进度
- Python实现采用进度条实时显示处理进度的方法
- 点击button触发JS函数,通过AJAX传值给后台查询,将返回值处理成table表格,添加到模态框里显示
- 通过Handler实现先显示进度条,后台进行数据处理,处理结束后取消进度条
- Web页面实现后台数据处理进度与剩余时间的显示
- 使用asp.net 2.0 客户端回调功能显示后台处理进度
- Python进度条实时显示处理进度的示例代码
- 在controller中返回ajax处理后结果,页面显示xmlObjectDocument的解决方法
- Android程序设计:显示后台任务进度对话框
- 基于ajax实现文件上传并显示进度条
- 一个可以实时显示进度的自定义view,类似于listview中音乐播放背景变化的效果