參考鏈接1
參考鏈接2
瀏覽器與服務(wù)器之間時(shí)采用HTTP協(xié)議通信的;如在地址欄輸入地址或者提交表單,瀏覽器都會(huì)向服務(wù)器發(fā)起請求;而AJAX是腳本向服務(wù)器發(fā)起HTTP請求的代名詞;
AJAX總結(jié)為以下步驟:
1.創(chuàng)建AJAX對象;
2.發(fā)起HTTP請求(只能是協(xié)議、域名、端口都相同的同源網(wǎng)址);
3.接收服務(wù)器傳回的數(shù)據(jù);
4.更新局部網(wǎng)頁數(shù)據(jù);
實(shí)例化XMLHttpRequest對象,使用它向服務(wù)器發(fā)出HTTP請求
httpRequest = new XMLHttpRequest();
提出請求后利用XMLHttpRequest實(shí)例的屬性——readyState相應(yīng)的值來獲得XMLHttpRequest請求當(dāng)前所處的狀態(tài);readyState有以下值:
| 整數(shù)值 | 對應(yīng)常量 | 請求所處狀態(tài) |
|---|---|---|
| 0 | UNSENT | 請求未初始化 |
| 1 | OPENED | 建立服務(wù)器連接 |
| 2 | HEADERS_RECEIVED | 請求收到 |
| 3 | LOADING | 處理請求 |
| 4 | DONE | 請求完成,響應(yīng)已準(zhǔn)備就緒 |
readyState屬性的值發(fā)生改變,就會(huì)觸發(fā)readyStateChange事件。此時(shí)我們可以通過onReadyStateChange屬性,指定這個(gè)事件的回調(diào)函數(shù),對不同狀態(tài)進(jìn)行不同處理。尤其是當(dāng)狀態(tài)變?yōu)?的時(shí)候,表示通信成功,這時(shí)回調(diào)函數(shù)就可以處理服務(wù)器傳送回來的數(shù)據(jù)。
接下來,通過status還要檢查HTTP響應(yīng)的響應(yīng)代碼;
| 狀態(tài)碼 | 狀態(tài) |
|---|---|
| 200 | 訪問正常 |
| 301 | 永久移動(dòng) |
| 302 | 暫時(shí)移動(dòng) |
| 401 | 未授權(quán) |
| 403 | 禁止訪問 |
| 404 | 未發(fā)現(xiàn)指定網(wǎng)址 |
| 500 | 服務(wù)器發(fā)生錯(cuò)誤 |
根據(jù)readyState、onReadyStateChange、status屬性,當(dāng)我們利用open方法和send發(fā)送HTTP請求時(shí),代碼如下:
httpRequest.onreadystatechange = alertContents;
httpRequest.open('GET', 'test.html');
httpRequest.send();
function alertContents() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
.....
} else {
......
}
}
}
open方法用于指定發(fā)送HTTP請求的參數(shù),一共可以接受五個(gè)參數(shù):
- method:表示HTTP動(dòng)詞,比如“GET”、“POST”、“PUT”和“DELETE”。
該請求所要訪問的URL; - url: 表示請求發(fā)送的網(wǎng)址。
- async: 默認(rèn)為true,表示請求為異步。如果設(shè)為false,則
send()方法-
只有等到收到服務(wù)器返回的結(jié)果,才會(huì)有返回值。 - user:表示用于認(rèn)證的用戶名,默認(rèn)為空字符串。
- password:表示用于認(rèn)證的密碼,默認(rèn)為空字符串。
send方法用于實(shí)際發(fā)出HTTP請求;如果不帶參數(shù),就表示HTTP請求只包含頭信息,也就是只有一個(gè)URL,典型例子就是GET請求;如果帶有參數(shù),就表示除了頭信息,還帶有包含具體數(shù)據(jù)的信息體,典型例子就是POST請求。如下兩個(gè)例子:
ajax.open('GET'
, 'http://www.example.com/somepage.php?id=' + encodeURIComponent(id)
, true
);
// 等同于
var data = 'id=' + encodeURIComponent(id);
ajax.open('GET', 'http://www.example.com/somepage.php', true);
ajax.send(data);
var data = 'email='
+ encodeURIComponent(email)
+ '&password='
+ encodeURIComponent(password);
ajax.open('POST', 'http://www.example.com/somepage.php', true);
ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajax.send(data);
上面代碼中的setRequestHeader方法用于設(shè)置HTTP頭信息。該方法必須在open()之后、send()之前調(diào)用;另外send方法的參數(shù)就是發(fā)送的數(shù)據(jù)。多種格式的數(shù)據(jù),都可以作為它的參數(shù)??梢允潜韱螖?shù)據(jù),Document數(shù)據(jù),JavaScript生成的文件,發(fā)送二進(jìn)制數(shù)據(jù),最好使用ArrayBufferView或Blob對象,這使得通過Ajax上傳文件成為可能。
在檢查請求的狀態(tài)(readyState)和響應(yīng)的HTTP狀態(tài)代碼(status)之后,通過response屬性獲得服務(wù)器返回的數(shù)據(jù);
它的類型由XMLHttpRequest.responseType屬性的值決定。默認(rèn)為字符串,如果本次請求沒有成功或者數(shù)據(jù)不完整,該屬性就會(huì)等于null;
- “arraybuffer”:ArrayBuffer對象
- “blob”:Blob對象
- “document”:Document對象
- “json”:JSON對象
- “text”:字符串
blob類型適合讀取二進(jìn)制數(shù)據(jù),比如圖片文件。參考以下代碼:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = new Blob([this.response], {type: 'image/png'});
// 或者
var blob = oReq.response;
}
};
xhr.send();
如果將這個(gè)屬性設(shè)為ArrayBuffer,就可以按照數(shù)組的方式處理二進(jìn)制數(shù)據(jù)。
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
for (var i = 0, len = binStr.length; i < len; ++i) {
// var byte = uInt8Array[i];
}
};
xhr.send();
responseText和responseXML分別返回從服務(wù)器接收到的字符串和Document對象;如下代碼:
var data = ajax.responseText;
data = JSON.parse(data);
如果想在請求的各種情況下做什么其他處理,可以使用可以使用事件監(jiān)聽接口:
- onloadstart 請求發(fā)出
- onprogress 正在發(fā)送和加載數(shù)據(jù)
- onabort 請求被中止,比如用戶調(diào)用了abort()方法
- onerror 請求失敗
- onload 請求成功完成
- ontimeout 用戶指定的時(shí)限到期,請求還未完成
- onloadend 請求完成,不管成果或失敗
httpRequest = new XMLHttpRequest();
function alertContents() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
.....
} else {
......
}
}
}
httpRequest.onreadystatechange = alertContents;
httpRequest.open('GET', 'test.html',true);
httpRequest.onerror = function () {
console.log("** An error occurred during the transaction");
};
httpRequest.send();
利用表單進(jìn)行文件上傳的時(shí)候
現(xiàn)有HTML代碼如下:
<form id="file-form" action="handler.php" method="POST">
<input type="file" id="file-select" name="photos[]" multiple/>
<button type="submit" id="upload-button">上傳</button>
</form>
JavaScript代碼如下:
var file = document.getElementById('test-input').files[0];
var xhr = new XMLHttpRequest();
xhr.open('POST', 'myserver/uploads');
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);