Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 318|回复: 0

[AJAX学习]让ajax实时显示后台处理进度。

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-13 00:50:01 | 显示全部楼层 |阅读模式
    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代码):     <%[/code]

         
    //
      下面设置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错误.

    出处:http://www.blogjava.net/BearRui/

      
      
       
       

         
       

         
       
      
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-26 06:55 , Processed in 0.378718 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表