使用
XMLHttpRequest
(XHR)對象可以與服務器交互。您可以從URL獲取數據,而無需讓整個的頁面刷新。這允許網頁在不影響用戶的操作的情況下更新頁面的局部內容。在 AJAX 編程中,XMLHttpRequest
被大量使用。
<br />
1. 理解XHR
- 使用XMLHttpRequest(XHR)對象可以與服務器交互,也就是發送ajax請求
- 前端可以獲取到數據,而無需讓整個頁面刷新
- 這使得Web頁面可以只更新頁面的局部,而不影響用戶的操作
區別一般http請求與ajax請求
- ajax請求是一種特別的http請求
- 對服務器端來說,沒有任何區別,區別在瀏覽器端
- 瀏覽器端發請求:只有XHR或fetch發出的纔是ajax請求,其他的所有請求都是非ajax請求
- 瀏覽器端接收到響應
- (1) 一般請求: 瀏覽器一般會直接顯示響應體數據, 也就是我們常說的刷新/跳轉頁面<br />
(2) ajax 請求: 瀏覽器不會對界面進行任何更新操作, 只是調用監視的回調 函數並傳入響應相關數
3. API
XMLHttpRequest():創建XHR對象的構造函數
status: 響應狀態碼值,比如200,404
statusText: 響應狀態文本
-
readyState: 標識請求狀態的只讀屬性
0: 初始<br /> 1: open()之後<br /> 2: send()之後<br /> 3: 請求中<br /> 4: 請求完成
onreadystatechange: 綁定readyState改變監聽
responseType: 指定相應數據,如果是'json',得到響應後自動解析響應體數據
response: 響應體數據,類型取決於responseType的指定
timeout: 指定請求超時時間,默認爲0代表沒限制
ontimeout: 綁定超時的監聽
onerror: 綁定請求網絡錯誤的監聽
open(): 初始化一個請求, 參數爲: (method, url[, async])
send(data): 發送請求
abort(): 中斷請求
getResponseHeader(name): 獲取指定名稱的響應頭值
getAllResponseHeaders(): 獲取所有響應頭組成的字符串<br />16. setRequestHeader(name, value): 設置請求頭
4. XHR的ajax封裝,也算是簡單版的axios
4.1 特點
- 函數的返回值promise,成功的結果爲response,異常的結果爲error
- 能處理多種類型的請求:GET/POST/PUT/DELETE
- 函數的參數爲一個配置對象
{
url: '', // 請求地址
method: '', // 請求方式 GET/POST/PUT/DELETE
params: {}, // GET/DELETE 請求的 query 參數
data: {}, // POST 或 DELETE 請求的請求體參數
}
- 響應json數據自動解析爲js的對象/數組
4.2 簡單版的axios源碼
function axios({
url,
method='GET',
params={},
data={}
}) {
// 返回一個promise對象
return new Promise((resolve, reject) => {
// 處理method(轉大寫)
method = method.toUpperCase()
// 處理query參數(拼接到url上) id=1&xxx=abc
/*
{
id: 1,
xxx: 'abc'
}
*/
let queryString = ''
Object.keys(params).forEach(key => {
queryString += `${key}=${params[key]}&`
})
if (queryString) { // id=1&xxx=abc&
// 去除最後的&
queryString = queryString.substring(0, queryString.length-1)
// 接到url
url += '?' + queryString
}
// 1. 執行異步ajax請求
// 創建xhr對象
const request = new XMLHttpRequest()
// 打開連接(初始化請求, 沒有請求)
request.open(method, url, true)
// 發送請求
if (method==='GET' || method==='DELETE') {
request.send()
} else if (method==='POST' || method==='PUT'){
request.setRequestHeader('Content-Type', 'application/json;charset=utf-8') // 告訴服務器請求體的格式是json
request.send(JSON.stringify(data)) // 發送json格式請求體參數
}
// 綁定狀態改變的監聽
request.onreadystatechange = function () {
// 如果請求沒有完成, 直接結束
if (request.readyState!==4) {
return
}
// 如果響應狀態碼在[200, 300)之間代表成功, 否則失敗
const {status, statusText} = request
// 2.1. 如果請求成功了, 調用resolve()
if (status>=200 && status<=299) {
// 準備結果數據對象response
const response = {
data: JSON.parse(request.response),
status,
statusText
}
resolve(response)
} else { // 2.2. 如果請求失敗了, 調用reject()
reject(new Error('request error status is ' + status))
}
}
})
}
如想了解更多請掃描二維碼,關注公衆號<br />