<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 36, comments - 419, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

     

    ajax應用越來越多,大部分ajax處理都是在前臺顯示1個"loading...",然后把數(shù)據(jù)提交給服務器進行處理,處理完畢后顯示"處理完畢"。
    我們能否讓ajax更加友好點,實時顯示服務器處理的進度了?這在一些長時間的請求中尤其重要,比如上傳文件、發(fā)送郵件、批量處理數(shù)據(jù)。
    答案當然是可以的,不然就不會寫這個了,對吧,^_^。

          ajax應用越來越多,大部分ajax處理都是在前臺顯示1個"loading...",然后把數(shù)據(jù)提交給服務器進行處理,處理完畢后顯示"處理完畢"。我們能否讓ajax更加友好點,實時顯示服務器處理的進度了?這在一些長時間的請求中尤其重要,比如上傳文件、發(fā)送郵件、批量處理數(shù)據(jù)。答案當然是可以的,不然就不會寫這個了,對吧,^_^。

     

     

    存在的問題:    

       要解決實現(xiàn)上面的功能,需要解決下面幾個問題:

       1. 服務器如何在處理一部分數(shù)據(jù)后傳遞部分response到瀏覽器。

       2、瀏覽器如何能處理服務器傳遞過來部分數(shù)據(jù),并保持http連接直到處理完全完畢。

     

       要解決第1個問題,使用flush讓response分塊進行呈現(xiàn)就可以了,具體請參考我另一遍隨筆"flush讓頁面分塊,逐步呈現(xiàn)";

       第2個問題,則需要用到XMLHttpRequest的readyState狀態(tài),w3c對 readyState 定義如下幾個值:

      UNSENT = 0; // 沒有發(fā)送請求

      OPENED = 1;    // 已經(jīng)打開http連接

      HEADERS_RECEIVED = 2; // 接收到response header

      LOADING = 3;          // 真正接收response body   

      DONE = 4;             // 請求接收完畢

       相信狀態(tài)4大家是天天在用,而我們這里需要用到就是狀態(tài)3。

     

     

    實例:  

         廢話少說,代碼實例比什么文字解釋都管用。我們這里假設服務器的1個處理需要6秒種,每秒種處理1條記錄,總共處理6條記錄,我們需要服務器每處理完1條數(shù)據(jù),客戶端則顯示處理進度(包括文字和進度條)。

     

       服務器端代碼(下面JSP代碼):

        <%
        // 下面設置Content-Type:application/x-javascript 是為了適應Webkit的瀏覽器(chrome,safari)
          response.setHeader("Content-Type","application/x-javascript");
          
    int count = 6;    //    處理6條數(shù)據(jù)
          for(int i=0;i<count;i++){
              
    // 處理完畢一條,輸出結果到客戶端
              out.println(i+1);
              out.flush();
              
    // 這里假設每條數(shù)據(jù)處理時間為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()">提交數(shù)據(jù)</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){ 
                        
    // 請求執(zhí)行完畢
                        t.innerHTML = "執(zhí)行完畢";
                        bg.style.width 
    = "300px";
                    }
                }
                xhr.send(
    null);
          }
        
    </script>
    </body>
    </html>

     

        運行效果圖: 

        

     

    缺點:

         看到這里或許你已經(jīng)蠢蠢欲動,想自己動手試試了。但是注意上面的方法雖好,但也有個缺點,就是瀏覽器的支持問題。目前IE所有版本的瀏覽器都不支持 xhr.readyState == 3狀態(tài),IE瀏覽器不支持在response響應完畢前讀取responseText屬性。  具體可查看MSDN :  XMLHttpRequest Object 

         基于Webkit的瀏覽器支持的不是很好,需要設置Content-Type:application/x-javascript才行(經(jīng)測試發(fā)現(xiàn)Content-Type:text/html在有些情況下正常,有些情況下又不正常,而用application/x-javascript都正常)。

         看到了缺點后是否又打擊了你的積極性了,其實針對IE,我們不需要做太多處理,IE不支持,就不會顯示進度,就變成跟傳統(tǒng)的ajax請求一樣,一直顯示1個loading直到請求完畢。我們只需要加1個簡單的判斷,判斷如果是ie則不執(zhí)行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.tkk7.com/bearrui/
    [聲明]:本博所有文章版權歸作者所有(除特殊說明以外),轉載請注明出處.
    英雄,別走啊,幫哥評論下:  

    精彩推薦 好文要頂 水平一般 看不懂 還需努力

    評論

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-02 12:32 by thebye85
    很不錯,謝謝分享

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-02 14:14 by 菠蘿大象
    為什么不用jQuery?jQuery的跨瀏覽器無疑是非常強大的。

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-02 14:17 by BearRui(AK-47)
    @thebye85
    謝謝支持

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-02 14:17 by BearRui(AK-47)
    @菠蘿大象
    jquery并沒有這樣的功能,jquery的ajax都是在readyState==4后才執(zhí)行代碼

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-03 11:30 by noname
    感謝分享,這種方法適用于時間比較長而且可以預期處理時間的場景,如果時間很短就沒有必要。還是很有意思的

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-03 12:17 by BearRui(AK-47)
    @noname
    的確是這樣,并不是所有情況都適合使用這種方法。

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-04 10:20 by @beyondwcm
    ajax 還可以多次 out.flush();

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-04 13:10 by 稅國政
    可惜ie不支持啊

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-04 13:12 by BearRui(AK-47)
    呵呵,是有利有弊的

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-06-24 13:31 by pandora jewels
    值得一看,都是專業(yè)人士啊!

    # re: 讓ajax更加友好,實時顯示后臺處理進度。[未登錄]  回復  更多評論   

    2010-07-13 18:27 by 123
    很想知道你在 ie 中 是怎么處理 readstatus > 3 的??應該總有解決的
    辦法吧??

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-07-13 20:31 by BearRui(AK-47)
    @123

    IE 不支持readstatus ,如果IE要支持這種功能,就需要采用ajax輪詢服務器來實現(xiàn)。

    # re: 讓ajax更加友好,實時顯示后臺處理進度。[未登錄]  回復  更多評論   

    2010-07-14 16:20 by 123
    換句話說,你的這種實現(xiàn)方式很好,但是 ie 不支持,火狐是可以的,
    我測試過了。。那你能不能有其他的方式去實現(xiàn)這種 后臺處理進度,然后再前臺實現(xiàn)呢?? 比如用jquery,或者 其他的ajax 框架,來實現(xiàn) 這種 處理進度條呢??很期待你的杰作。。如果有,請發(fā)我的郵箱:ypcheng@yeah.net,
    謝謝!!!

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2010-07-15 13:15 by BearRui(AK-47)
    @123
    這種我也做過1個,是做數(shù)據(jù)導入的時候,使用ajax輪詢請求服務器上的導入進度,然后再前臺顯示,看找個時間寫出來。

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2012-05-21 13:19 by jidebingfeng
    好文章,頂一下!

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2012-05-21 13:19 by jidebingfeng
    文章很精彩,推薦一下!

    # re: 讓ajax更加友好,實時顯示后臺處理進度。  回復  更多評論   

    2014-07-17 17:20 by aliang
    jquery 1.5+應該可以實現(xiàn)吧

    var orgAjax = jQuery.ajaxSettings.xhr;
    jQuery.ajaxSettings.xhr = function () {
    var xhr = orgAjax();
    xhr.onreadystatechange = function() {
    alert(xhr.readyState)
    }
    return xhr;
    };
    主站蜘蛛池模板: 日韩免费的视频在线观看香蕉| h视频在线免费看| 久久精品亚洲综合| 日本黄网站动漫视频免费| 亚洲JIZZJIZZ妇女| 久久亚洲精品无码| 国产男女猛烈无遮挡免费视频网站| 精品多毛少妇人妻AV免费久久| 亚洲精品国产专区91在线| 四虎影视在线永久免费看黄| 人妻丰满熟妇无码区免费| 国产精品亚洲一区二区三区| 亚洲国产人成网站在线电影动漫 | 亚洲精品精华液一区二区| 亚洲中文字幕在线乱码| 毛片免费全部免费观看| 久久久久久久久久久免费精品| 亚洲国产成人精品青青草原| 亚洲午夜福利717| 免费无码黄动漫在线观看| 久9热免费精品视频在线观看| 亚洲成在人线在线播放无码| 久久99亚洲网美利坚合众国 | 亚洲国产精品成人久久| 四虎影视免费在线| 最近2019免费中文字幕6| 四虎永久在线精品免费一区二区| 亚洲成a人片77777群色| 亚洲日韩精品无码一区二区三区 | 韩国免费三片在线视频| 亚洲午夜免费视频| 国产高清对白在线观看免费91| 亚洲性无码av在线| 亚洲va在线va天堂va888www| 亚洲日韩在线第一页| 日韩精品视频免费在线观看| 18勿入网站免费永久| 日本xxxx色视频在线观看免费| 久青草视频97国内免费影视| 老司机福利在线免费观看| 亚洲乱妇熟女爽到高潮的片|