1、xmlHttpRequest level1:
xmlHttpRequest是一個浏覽器腳本語言,用來給server發送http或者https請求來加載,出于安全考慮,這個隻能用于同域通路(還有其他的缺點,比如說不能讀取或者上傳二進制檔案,傳送和發送資料時沒有進度資訊)。Xmlhttprequest概念的形成是源于微軟的outlook web access,後來使用這樣的概念形成了msxml庫,這就是為什麼在以前的IE版本中通過依賴msxml庫的控件的形式建立一個XMLhttprequest對象,這個對象在1999年3月份由IE5引入,2006年10月在IE7中正式支援xmlhttprequest對象。
随着jquery,dojo庫(架構)的興起,原生的xmlhttprequest對象更是慢慢地淡出了人們地視線,他們這些庫都是将xmlhttprequest進行了封裝,暴露出更加好用的方法。2008年2月,W3C推出了xmlhttprequest level2的草案,增加了很多新的特性,今天我們将詳細地介紹下這些特性。
首先,我們先回歸一下在最初的版本中是怎麼使用xmlhttprequest對象的。IE5和IE6是怎麼建立的:
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
其他的浏覽器則通過 var xhr = new XMLHttpRequest()建立。
發送請求 :
xhr.open("GET","test1.txt",true);//啟動一個請求準備發送
xhr.send(); //發送請求
接下來就是等待伺服器的響應,這期間會有幾個狀态的變化,每個readyState的變化都會觸發下面的方法:
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 && xhr.status == 200 ) {
alert( xhr.responseText );
} else {
alert( xhr.statusText );
}
};
補充一點内容:
readyState的幾個狀态值(http的狀态請檢視《http權威指南》):
0: 請求未初始化
1: 伺服器連接配接已建立
2: 請求已接收
3: 請求進行中
4: 請求已完成,且響應已就緒
xhr傳回的資料類型:
xhr.responseText:傳回的文本資料
xhr.responseXML:傳回XML格式的資料
xhr.statusText:傳回狀态文本。
2、xmlHttpRequest level2
(後文說之的xhr對象之的是level2的)
(1)FormData
web中頻繁使用的就是表單資料的序列化了,Level2為此定義了一個FormData,可以通過給這個對象設定的屬性,
var formData = new FormData();
formData.append('username', '張三');
formData.append('id', 123456);
也可以使用表單資料預制FormData
var formData = new FormData(document.form[0]);
有了formDat後,就可以傳給xhr的send方法。使用FormData的友善之處就是不必明确地在xhr對象上設定頭部,即如下:
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
注:xhr level1模拟送出表單資料時要加上上述語句,因為post和web表單送出是不同的内容。
(2)timeout
timeout屬性最初是在IE8中引入的,後來也被w3c收入到了Level2的規範中,代碼片段如下:
xhr.open("GET","test1.txt",true)
xhr.timeout = 1000;//1秒後請求失效
xhr.ontimeout = function(){
}
(3)接受二進制資料
方法一:
改寫資料的MIMEType,将伺服器傳回的二進制資料僞裝成文本資料,并且告訴浏覽器這是使用者自定義的字元集,然後,
用responseText屬性接收伺服器傳回的二進制資料。
xhr.overrideMimeType("text/plain; charset=x-user-defined");
var binStr = xhr.responseText;
這時,浏覽器把它當做文本資料,是以還必須再一個個位元組地還原成二進制資料
for (var i = 0, len = binStr.length; i < len; ++i) {
var c = binStr.charCodeAt(i);
var byte = c & 0xff;
}
方法二:
使用新增的responseType屬性。如果伺服器傳回文本資料,這個屬性的值是"TEXT",這是預設值。較新的浏覽器還支援其他值,也就是說,可以接收其他格式的資料。你可以把responseType設為 blob,表示伺服器傳回的是二進制對象
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/p_w_picpath.png');
xhr.responseType = 'blob';
接收資料的時候,用浏覽器自帶的Blob對象即可。
var blob = new Blob([xhr.response], {type: 'p_w_picpath/png'});
你還可以将responseType設為arraybuffer,把二進制資料裝在一個數組裡。
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/p_w_picpath.png');
xhr.responseType = "arraybuffer";
接收資料的時候,需要周遊這個數組。
var arrayBuffer = xhr.response;
if (arrayBuffer) {
var byteArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteArray.byteLength; i++) {
// do something
}
}
(4)進度資訊
xhr level2對象在傳送資料的時候,有一個progress對象,用來傳回進度資訊,分為上傳還下載下傳兩種情況,下載下傳的progress事件屬于
xmlhttprequest對象,上傳的屬于xmlhttprequest.upload對象
xhr.onprogress = updateProgress;
xhr.upload.onprogress = updateProgress;
function updateProgress(event) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total;
}
}
還有其他的事件類型:
load事件:傳輸成功完成。
abort事件:傳輸被使用者取消。
error事件:傳輸中出現錯誤。
loadstart事件:傳輸開始。
loadEnd事件:傳輸結束,但是不知道成功還是失敗。
(5)CORS
下次介紹
參考内容:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
https://dev.opera.com/articles/xhr2/
http://cssor.com/cross-origin-resource-sharing.html
https://xhr.spec.whatwg.org/#interface-formdata
http://www.html5rocks.com/en/tutorials/file/xhr2/
http://www.w3school.com.cn/xmldom/dom_http.asp
https://dev.opera.com/articles/dom-access-control-using-cors/