1. 簡單實(shí)現(xiàn)
// 實(shí)例化
let xhr = new XMLHttpRequest()
// 初始化
xhr.open(method, url, async)
// 發(fā)送請求
xhr.send(data)
// 設(shè)置狀態(tài)變化回調(diào)處理請求結(jié)果
xhr.onreadystatechange = () => {
if (xhr.readyStatus === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
2. 基于promise實(shí)現(xiàn)
function ajax (options) {
// 請求地址
const url = options.url
// 請求方法
const method = options.method.toLocaleLowerCase() || 'get'
// 默認(rèn)為異步true
const async = options.async
// 請求參數(shù)
const data = options.data
// 實(shí)例化
const xhr = new XMLHttpRequest()
// 請求超時(shí)
if (options.timeout && options.timeout > 0) {
xhr.timeout = options.timeout
}
// 返回一個(gè)Promise實(shí)例
return new Promise ((resolve, reject) => {
xhr.ontimeout = () => reject && reject('請求超時(shí)')
// 監(jiān)聽狀態(tài)變化回調(diào)
xhr.onreadystatechange = () => {
if (xhr.readyState == 4) {
// 200-300 之間表示請求成功扮宠,304資源未變麸祷,取緩存
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
resolve && resolve(xhr.responseText)
} else {
reject && reject()
}
}
}
// 錯(cuò)誤回調(diào)
xhr.onerror = err => reject && reject(err)
let paramArr = []
let encodeData
// 處理請求參數(shù)
if (data instanceof Object) {
for (let key in data) {
// 參數(shù)拼接需要通過 encodeURIComponent 進(jìn)行編碼
paramArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
}
encodeData = paramArr.join('&')
}
// get請求拼接參數(shù)
if (method === 'get') {
// 檢測url中是否已存在 ? 及其位置
const index = url.indexOf('?')
if (index === -1) url += '?'
else if (index !== url.length -1) url += '&'
// 拼接url
url += encodeData
}
// 初始化
xhr.open(method, url, async)
// 發(fā)送請求
if (method === 'get') xhr.send(null)
else {
// post 方式需要設(shè)置請求頭
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8')
xhr.send(encodeData)
}
})