1. 程式人生 > >一些XMLHttpRequest的例子程式碼

一些XMLHttpRequest的例子程式碼

以下例子摘錄自:javascript權威指南

//非同步請求(事件監聽請求是否返回)
function getText(url,callback){
    var request = new XMLHttpRequest();
    request.open('GET',url);
    request.onreadystatechange = function () {
        if(request.readyState === 4 && request.status === 200){
            var type = request.getResponseHeader('Conten-Type'
); if(type.match(/^text/)){ callback(request.responseText); } } }; request.send(null); }
//同步請求(會阻塞頁面)
function getTextSync(url){
    var request = new XMLHttpRequest();
    request.open('GET',url,false); //false表示同步請求
    request.send(null);
    if(request.status !== 200
){ throw new Error('..'); } var type = request.getResponseHeader('Conten-Type'); if(!type.match(/^text/)){ throw new Error('....'); } return request.responseText; }
//解析HTTP請求響應
function get(url,callback){
    var request = new XMLHttpRequest();
    request.open('GET'
,url); request.onreadystatechange = function(){ if(request.readyState === 4 && request.status === 200){ var type = request.getResponseHeader('Content-Type'); if(type.indexOf('xml') !== -1 && request.responseXML){ callback(request.responseXML); }else if(type === 'application/json'){ callback(JSON.parse(request.responseText)); }else{ callback(request.responseText); } } }; request.send(null); }

非表單資料形式的表單編碼的請求GET和提交POST(如data物件)

//1.將儲存有(名:值)對屬性的data物件轉化為整個字串
function encodeFormData(data){
    if(!data){return ''}
    var pairs = [];  //儲存名=值對
    for(var name in data){
        if(data.hasOwnProperty(name) && typeof data[name] !== 'function'){
            var value = data[name].toString();
            name = encodeURIComponent(name.replace('%20','+'));
            value = encodeURIComponent(value.replace('%20','+'));
            pairs.push(name+'='+value);
        }
    }
    return pairs.join('&');
}
//2.直接傳送data物件的HTTP POST請求工具函式
function postData(url,data,callback){
    var request = new XMLHttpRequest();
    request.open('POST',url);
    request.onreadystatechange = function () {
        if(request.readyState === 4 && callback){
            callback(request); //將request物件傳遞給callback處理
        }
    };
    request.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    request.send(encodeFormData(data));
}
//3.若表單資料只是為了只讀查詢,則最好用GET方法,在url+'?'+查詢字串
function getData(url,data,callback){
    var request = new XMLHttpRequest();
    request.open('GET',url+'?'+encodeFormData(data));
    request.onreadystatechange = function(){
        if(request.readyState === 4 && callback){
            callback(request);
        }
    };
    request.send(null);
}
//4.使用JSON編碼主體來發起HTTP POST請求
function postJSON(url,data,callback){
    var request = new XMLHttpRequest();
    request.open('POST',url);
    request.onreadystatechange = function () {
        if(request.readyState === 4 && callback){
            callback(request);
        }
    };
    request.setRequestHeader('Content-Type','application/json');
    request.send(JSON.stringify(data));
}
//5.使用POST傳送multipart/form-data請求主體
function postFormData(url,data,callback){
    if(FormData){throw new Error('FormData is not implemented')}
    var request = new XMLHttpRequest();
    request.open('POST',url);
    request.onreadystatechange = function () {
        if(request.readyState === 4 && callback){
            callback(request);
        }
    };
    //建立一個FormData物件的例項
    var formdata = new FormData();
    for(var name in data){
        if(data.hasOwnProperty(name) && typeof data[name] !== 'function'){
            formdata.append(name,data[name]);
        }
    }
    request.send(formdata);
}
//6.終止請求和超時(在文字輸入域請求推薦內容時,如果使用者在伺服器的建議達到之前輸入了新的字元,則應該終止請求)
function timedGetText(url,delay,callback){
    var request = new XMLHttpRequest();
    var timedOut = false;
    //啟動計時器,在delay時間到後將終止請求
    var id = setTimeout(function () {
        timedOut = true;
        request.abort();
    },delay);
    request.open('GET',url);
    request.onreadystatechange = function () {
        if(timedOut||request.readyState !== 4){return}
        clearTimeout(id);
        if(request.status === 200){
            callback(request.responseText);
        }
    };
    request.send(null);
}

7.HTTP進度事件
XMLHttpRequest物件在請求的不同階段觸發不同型別的事件,所以它不需要檢查readyState屬性。
當呼叫send()時,觸發單個loadstart事件。當正在載入伺服器的響應時,XMLHttpRequest物件會發生progress事件,通常每隔50毫秒左右,所以可以使用這些事件給使用者反饋請求的進度
如果請求快速完成,它可能從不會觸發progress事件。當事件完成,會觸發load事件。
HTTP請求無法完成有3種情況,對應3種事件。如果請求超時,會觸發timeout事件。如果請求中止,會觸發abort事件。像太多重定向這樣的網路錯誤會阻止請求完成,但這些情況發生時會觸發error事件。
對於任何具體請求,瀏覽器將只會觸發load、abort、timeout和error事件中的一個。
progress事件屬性:loaded目前傳輸的位元組數值,total是自“Content-Length”頭傳輸的資料的整體長度(位元組),如果未知長度則為0,若知道長度則lengthComputable屬性為true

if('onprogress' in (new XMLHttpRequest())){ //檢測是否支援progress事件
    var request = new XMLHttpRequest();
    request.onprogress = function (e) {
        if(e.lengthComputable){
            progress.innerHTML = Math.round(100* e.loaded/ e.total) + '%';
        }
    }
}

對於XMLHttpRequest物件x,設定x.onprogress以監控響應的下載進度,並且設定x.upload.onprogress以監控請求的上傳進度。

8.跨域HTTP請求
//XMLHttpRequest物件通常僅可以發起和文件具有相同伺服器的HTTP請求。
//XHR2通過在HTTP響應中選擇傳送合適的CORS( Cross- Origin Resource Sharing, 跨域資源共享)允許跨域訪問網站。
//而IE8通過這裡沒有列出的專用XDomainRequest物件支援它。
//如果給XMLHttpRequest的open()方法傳入使用者名稱和密碼,那麼它們絕對不會通過跨域請求傳送
//除外,跨域請求通常也不會包含其他任何的使用者證書:cookie和HTTP身份驗證令牌( token)通常不會作為請求的內容部分發送且任何作為跨域響應來接收的cookie都會丟棄。
//如果跨域請求需要這幾種憑證才能成功,那麼必須在用send()傳送請求前設定XMLHttpRequest的withCredentials屬性為true。這樣做不常見,但測試withCredentials的存在性是測試瀏覽器是否支援CORS的方法

whenReady(
    function () {
        var supportsCORS = (new XMLHttpRequest()).withCredentials !== (void 0);
        var links = document.getElementsByTagName('a');
        for(var i=0;i<links.length;i++){
            var link = links[i];
            if(!link.href || link.title){continue;}
            //如果是跨域連結
            if(link.host !== location.host || link.protocol !== location.protocol){
                link.title = '這是站外連結';
                if(!supportsCORS){continue;} //不支援CORS就退出
            }
            if(link.addEventListener){
                link.addEventListener('mouseover',mouseoverHandler,false);
            }else{
                link.attachEvent('onmouseover',mouseoverHandler);
            }
        }
        function mouseoverHandler(event){
            var e = event||window.event;
            var link = e.target|| e.srcElement;
            var url = link.href;
            var request = new XMLHttpRequest();
            request.open('HEAD',url);
            request.onreadystatechange = function () {
                if(request.readyState === 4 || request.status === 200){
                    var type = request.getResponseHeader('Content-Type');
                    var size = request.getResponseHeader('Content-Length');
                    var date = request.getResponseHeader('Last-Modified');
                    link.title = '型別: '+type+' \n'+'大小: '+size+' \ n'+'時間: '+date;
                }else if(!link.title){
                    link.title = "Couldn't fetch details:\n"+request.status+" "+request.statusText;
                }
            };
            request.send(null);
            if(link.removeEventListener){
                link.removeEventListener('mouseover',mouseoverHandler,false);
            }else{
                link.detachEvent('onmouseover',mouseoverHandler);
            }
        }
    }
);