让ajax更加友好的实现方法(实时显示后台处理进度。)_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代码):

复制代码 代码如下:

<%
// 下面设置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代码:

复制代码 代码如下:

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

时间: 2025-01-30 13:19:37

让ajax更加友好的实现方法(实时显示后台处理进度。)_AJAX相关的相关文章

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

ajax应用越来越多,大部分ajax处理都是在前台显示1个"loading...",然后把数据提交给服务器进行处理,处理完毕后显示"处理完毕".我们能否让ajax更加友好点,实时显示服务器处理的进度了?这在一些长时间的请求中尤其重要,比如上传文件.发送邮件.批量处理数据.答案当然是可以的,不然就不会写这个了,对吧,^_^. 存在的问题: 要解决实现上面的功能,需要解决下面几个问题: 1. 服务器如何在处理一部分数据后传递部分response到浏览器. 2.浏览器如何

AJAX实现跨域的三种方法(代理,JSONP,XHR2)_AJAX相关

域: 域是WIN2K网络系统的安全性边界.我们知道一个计算机网最基本的单元就是"域",这一点不是WIN2K所独有的,但活动目录可以贯穿一个或多个域.在独立的计算机上,域即指计算机本身,一个域可以分布在多个物理位置上,同时一个物理位置又可以划分不同网段为不同的域,每个域都有自己的安全策略以及它与其他域的信任关系.当多个域通过信任关系连接起来之后,活动目录可以被多个信任域域共享. 由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只

jQuery通过Ajax向PHP服务端发送请求并返回JSON数据_AJAX相关

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写,同时也易于机器解析和生成.JSON在前后台交互的过程中发挥着相当出色的作用. 服务端PHP读取MYSQL数据,并转换成JSON数据,传递给前端Javascript,并操作JSON数据.本文将通过实例演示了jQuery通过Ajax向PHP服务端发送请求并返回JSON数据.阅读本文的读者应该具备jQuery.Ajax.PHP相关知识,并能熟练运用. XHTML <ul id="use

ajax快速解决参数过长无法提交成功的问题_AJAX相关

查了很多资料都说,get方法的参数是有限制的,post方法的参数的长度是无限制,这也是post相比get的优势一直. 在ajax中使用post方法,用常规的参数格式:param1=a1&param2=a2 ,当参数长度过长时,依然提交不成功.比如我们经常这样写一个ajax的post请求: $.ajax({ type: "post", // post or get contentType:"application/json;charset=utf-8", da

Ajax的jsonp方式跨域获取数据的简单实例_AJAX相关

jsonp的调用,今天碰到了,正好整理了一下. <!DOCTYPE html> <html> <head> <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#b

各种AJAX方法的使用比较详解_AJAX相关

阅读目录 开始 第一代技术:生成客户端代理脚本调用服务端 新技术的改进方向 第二代技术:jQuery直接调用WebService 第三代技术:更简单的数据格式 第四代技术:直接提交表单 多submit按钮的提交(用jQuery.form实现) 批量输入控件的提交(用jQuery.form实现) 提交复杂表单(用jQuery.form实现) 各种AJAX开发方法的对比与总结 相关链接 本文收集了在ASP.NET平台上,一些具体代表性的AJAX开发方法,我将用实际的示例代码来演示如何使用它们,让您感

jQuery ajax中使用serialize()方法提交表单数据示例_AJAX相关

jQuery ajax中数据以键值对(Key/Value)的形式发送到服务器,使用ajax提交表单数据时可以使用jQuery ajax的serialize() 方法表单序列化为键值对(key1=value1&key2=value2-)后提交.serialize() 方法使用标准的 URL-encoded 编码表示文本字符串.下面是使用serialize()序列化表单的实例: 复制代码 代码如下: $.ajax({   type: "POST",   url: ajaxCallU

$.ajax()方法进行网页间传值示例_AJAX相关

ajaxtext1.jsp 复制代码 代码如下: <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <script type="text/javascript" language="javascript" src="jquery.js"></script> <

AJAX 实时读取输入文本(php)_AJAX相关

客户端代码: 复制代码 代码如下: <!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> <meta http-eq