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

2016-02-19 10:41 61 1 收藏

下面是个简单易学的让ajax更加友好的实现方法(实时显示后台处理进度)教程,图老师小编详细图解介绍包你轻松学会,喜欢的朋友赶紧get起来吧!

【 tulaoshi.com - Web开发 】

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/。 禁止商用!

来源:https://www.tulaoshi.com/n/20160219/1595502.html

延伸阅读
标签: Web开发
我曾使用过的方法有三种: 1 在页面中加入隐藏的button,并定义了事件,然后执行js的$("#隐藏btnID").click()来 执行后台方法 2 用ajaxPro来执行 3 用ajax的url:页面地址/(静态)方法名称 来执行 在这种方法中,方法必须要求是静态的,所以例如在_default这个页面中 ,示例如下 代码如下: public partial class _Default : System.Web....
标签: Web开发
动机:         2006年底Google了一下AJAX Upload实现,结果没有发现很完整的Java实现。硕果仅存的就是TELIO公司的Pierre-Alexandre发表的《AJAX Upload progress monitor for Commons-FileUpload Example》文中提供的ajax-upload-1.0.war。         虽然...
标签: Web开发
网上已经有很多Web进度条的例子,但是很多都是估算时间,不能正真反应任务的真实进度。我自己结合多线程和ShowModalDialog制做了一个实时进度条,原理很简单:使用线程开始长时间的任务,定义一个Session,当任务进行到不同的阶段改变Session的值,线程开始的同时使用ShowModalDialog打开一个进度条窗口,不断刷新这个窗口获取Session值,...
使用 CSS 实现垂直居中并不容易。有些方法在一些浏览器中无效。下面我们看一下使对象垂直集中的5种不同方法,以及它们各自的优缺点。 方法一 这个方法把一些 div 的显示方式设置为表格,因此我们可以使用表格的 vertical-align property 属性。 div id="wrapper" div id="cell" div class="content" Content...
标签: Web开发
1.引言 2.实现代码 2.1.服务器端代码 2.1.1. 文件上传状态类(FileUploadStatus) 2.1.2. 文件上传状态侦听类(FileUploadListener) 2.1.3. 后台服务类(BackGroundService) 2.1.4. 文件上传状态控制类(BeanControler) 2.2. 客户端代码 2.2.1. AjaxWrapper.js 2.2.2. fileUpload.html 2.2.3. result.jsp 2.2.4. fileUpload.css 2.3. 配置文...

经验教程

772

收藏

60
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部