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

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

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

    聶永的博客

    記錄工作/學(xué)習(xí)的點(diǎn)點(diǎn)滴滴。

    Servlet 3.0筆記之異步請(qǐng)求Comet推送XMLHttpRequest示范

    說實(shí)話,各個(gè)瀏覽器對(duì)XMLHttpRequest內(nèi)置對(duì)象請(qǐng)求異步連接(或者稱呼為長連接)的支持不一而足,除了Firefox,Safari,IE8等,其它的要么不支持,要么有缺陷。總之,單純依靠XHR(XMLHttpRequest的簡稱)來調(diào)用長連接,不靠譜。
    XMLHttpRequest對(duì)象在標(biāo)準(zhǔn)情況下,在請(qǐng)求長連接情況下,readyState = 3時(shí)處于一直監(jiān)聽情況,但各大主流瀏覽器內(nèi)的支持相關(guān)情況不盡相同:
    1. IE(IE6-IE7),只有在請(qǐng)求的內(nèi)容不再發(fā)生變化時(shí)以及 readyState = 4 的時(shí)候才會(huì)獲取到返回的responseText內(nèi)容,因此不支持長連接。
    2. IE8:以XDomainRequest取代ActiveXObject對(duì)象,也算是一個(gè)進(jìn)步,但在服務(wù)器端有邀請(qǐng),必須在頭部設(shè)置 Access-Control-Allow-Origin值,若不知道客戶端調(diào)用JS所處的域名,設(shè)置成星號(hào),通用即可。
    3. Opera:貌似只有在readyState=3時(shí)才會(huì)觸發(fā)一次onreadystatechange函數(shù),不支持長連接。
    4. Firefox 3.6 和Safari 4:默認(rèn)支持XMLHttpRequest Streaming。
    5. Chrome 4.1版本:只有在請(qǐng)求內(nèi)容不再發(fā)生變化才會(huì)達(dá)到readyState=2狀態(tài),所以支持情況不太好。
    要檢測各個(gè)瀏覽器對(duì)XMLHttpRequest的支持請(qǐng)求,這里有一個(gè)好的去處:
     Streaming Test page 
    以上內(nèi)容,翻譯摘選自:COMET Streaming in Internet Explore 
    一個(gè)客戶端訂閱頁面:
     page
    頁面代碼:
    <html>
    <head>
    <title>comet XHR測試</title>
    <meta http-equiv="X-UA-Compatible" content="IE=8" />
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
    <meta name="author" content="yongboy@gmail.com" />
    <meta name="keywords" content="servlet3, comet, ajax" />
    <meta name="description" content="" />
    <link type="text/css" rel="stylesheet" href="css/main.css" />
    </head>
    <body style="margin: 0; overflow: hidden" onload="">
    <div id="showDiv" class="inputStyle"></div>
    <script>
    function showMsg(msg) {
    document.getElementById("showDiv").innerHTML = msg;
    }
    function doXHR() {
    var xhr = null;
    // 在IE8下面,window.XMLHttpRequest = true,因此需要window.XDomainRequest放在第一位置
    if (window.XDomainRequest) {
    xhr = new XDomainRequest();
    } else if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
    var aVersions = [ "Msxml2.XMLHttp.5.0", "Msxml2.XMLHttp.4.0",
    "Msxml2.XMLHttp.3.0", "Msxml2.XMLHttp", "Microsoft.XMLHttp" ];
    for ( var i = 0; i < aVersions.length; i++) {
    try {
    xhr = new ActiveXObject(aVersions[i]);
    break;
    } catch (e) {
    }
    }
    }

    if (xhr == null) {
    showMsg("當(dāng)前瀏覽器不支持創(chuàng)建XMLHttpRequest !");
    return;
    }

    try {
    xhr.onload = function() {
    showMsg(xhr.responseText);
    };
    xhr.onerror = function() {
    showMsg("XMLHttpRequest Fatal Error.");
    };
    xhr.onreadystatechange = function() {
    try {
    if (xhr.readyState > 2) {
    showMsg(xhr.responseText);
    }
    } catch (e) {
    showMsg("XMLHttpRequest Exception: " + e);
    }
    };
    // 經(jīng)測試:
    // IE8,Safayi完美支持onprogress事件(可以不需要onreadystatechange事件);
    // Chrome也支持,在后臺(tái)數(shù)據(jù)推送到時(shí),會(huì)調(diào)用其方法,但無法得到responseText值;除非(長連接關(guān)閉)
    // Firefox 3.6 也支持,但得到返回值有些BUG
    xhr.onprogress = function() {
    showMsg(xhr.responseText);
    };
    xhr.open("GET", "getnew?" + Math.random(), true);
    xhr.send(null);
    } catch (e) {
    showMsg("XMLHttpRequest Exception: " + e);
    }
    }
    if (window.addEventListener) {
    window.addEventListener("load", doXHR, false);
    } else if (window.attachEvent) {
    window.attachEvent("onload", doXHR);
    }
    </script>
    </body>
    </html>
    當(dāng)然后臺(tái)需要一個(gè)內(nèi)容發(fā)布的頁面:
    write2
    后臺(tái)處理的代碼和上篇隱藏IFrame服務(wù)器推送部分較為類似相似:
    /**
    * XHR獲取最新信息
    *
    * @author yongboy
    * @date 2011-1-10
    * @version 1.0
    */
    @WebServlet(urlPatterns = "/getnew", asyncSupported = true)
    public class GetNewBlogPosts extends HttpServlet {
    private static final long serialVersionUID = 5656988888865656L;
    private static final Log log = LogFactory.getLog(GetNewBlogPosts.class);

    protected void doGet(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    response.setHeader("Cache-Control", "private");
    response.setHeader("Pragma", "no-cache");
    response.setHeader("Connection", "Keep-Alive");
    response.setHeader("Proxy-Connection", "Keep-Alive");
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setContentType("text/html;charset=UTF-8");
    response.setCharacterEncoding("UTF-8");
    PrintWriter writer = response.getWriter();

    // 若當(dāng)前輸出內(nèi)容較少情況下,需要產(chǎn)生大約2KB的垃圾數(shù)據(jù),諸如下面產(chǎn)生一些空格
    for (int i = 0; i < 10; i++) {
    writer.print(" ");
    }

    writer.println("<div class='logDiv,clear'>waiting for ......</div>");
    writer.flush();

    final AsyncContext ac = request.startAsync();
    // 設(shè)置成長久鏈接
    ac.setTimeout(10 * 60 * 1000);
    ac.addListener(new AsyncListener() {
    public void onComplete(AsyncEvent event) throws IOException {
    NewBlogXHRListener.ASYNC_XHR_QUEUE.remove(ac);
    }

    public void onTimeout(AsyncEvent event) throws IOException {
    NewBlogXHRListener.ASYNC_XHR_QUEUE.remove(ac);
    }

    public void onError(AsyncEvent event) throws IOException {
    NewBlogXHRListener.ASYNC_XHR_QUEUE.remove(ac);
    }

    public void onStartAsync(AsyncEvent event) throws IOException {
    log.info("now add the AsyncContext");
    }
    });

    NewBlogXHRListener.ASYNC_XHR_QUEUE.add(ac);
    }
    }
    不過多了兼容IE8的代碼部分:
    response.setHeader("Access-Control-Allow-Origin", "*");
    在IE8以及Chrome平臺(tái)下,需要預(yù)先生成一些大小為2K的垃圾數(shù)據(jù),諸如一些空格。

    單獨(dú)線程代碼和上篇隱藏IFrame服務(wù)器推送部分相似,這里不再貼出。
    經(jīng)測試:
    1. 在ubuntu 10.10系統(tǒng)下Chrome(版本號(hào)8.0.552.224),支持XHR Streaming,測試通過。
    2. 2.Firefox 3.6 下測試通過。
    3. Safari 5.0.3 測試通過。
    4. IE8測試通過。

    posted on 2011-01-13 10:20 nieyong 閱讀(2362) 評(píng)論(0)  編輯  收藏 所屬分類: Servlet3

    公告

    所有文章皆為原創(chuàng),若轉(zhuǎn)載請(qǐng)標(biāo)明出處,謝謝~

    新浪微博,歡迎關(guān)注:

    導(dǎo)航

    <2011年1月>
    2627282930311
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345

    統(tǒng)計(jì)

    常用鏈接

    留言簿(58)

    隨筆分類(130)

    隨筆檔案(151)

    個(gè)人收藏

    最新隨筆

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲女同成av人片在线观看| 国产亚洲综合久久系列| 亚洲国产一区二区三区在线观看| 成人免费毛片视频| 久久免费观看国产99精品| 国产精品亚洲av色欲三区| 亚洲欧洲日产国码www| 亚洲精品国产字幕久久不卡| 日韩精品无码专区免费播放| 一级人做人爰a全过程免费视频| 亚洲国产人成网站在线电影动漫| 一级女人18毛片免费| 国产精品免费观看调教网| 一级女人18片毛片免费视频| 亚洲电影一区二区| 日韩精品视频免费网址| 国产h视频在线观看免费| 99蜜桃在线观看免费视频网站| 亚洲乱色伦图片区小说| 亚洲综合偷自成人网第页色| 亚洲一区二区三区高清| 亚洲AV无码精品色午夜在线观看| 一个人在线观看视频免费| 有码人妻在线免费看片| 美女被爆羞羞网站在免费观看| 亚洲ⅴ国产v天堂a无码二区| 美女黄网站人色视频免费国产| 青柠影视在线观看免费高清| 精品国产污污免费网站入口在线| 亚洲人成777在线播放| 亚洲精品和日本精品| 亚洲 小说区 图片区 都市| 日韩中文字幕免费视频| 一区二区三区在线免费看| 国产亚洲综合久久| 男性gay黄免费网站| 亚洲国产综合第一精品小说| 久久狠狠高潮亚洲精品| 亚洲日韩国产精品乱| 国产亚洲?V无码?V男人的天堂| 成年人免费视频观看|