如何手写一个简单的 Ajax 封装(支持 Promise)?
请手写一个基于 XMLHttpRequest 的 Ajax 函数,支持 GET/POST、超时、请求头配置,返回 Promise。
回答
苦行僧
function ajax(options) {
const {
url,
method = 'GET',
data = null,
headers = {},
timeout = 0,
responseType = ''
} = options;
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method.toUpperCase(), url, true);
if (timeout > 0) xhr.timeout = timeout;
if (responseType) xhr.responseType = responseType;
// 设置请求头
Object.keys(headers).forEach(key => {
xhr.setRequestHeader(key, headers[key]);
});
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(new Error(`HTTP ${xhr.status}: ${xhr.statusText}`));
}
};
xhr.onerror = () => reject(new Error('网络错误'));
xhr.ontimeout = () => reject(new Error('请求超时'));
xhr.onabort = () => reject(new Error('请求取消'));
// 处理请求体
let body = data;
if (data && typeof data === 'object' && !(data instanceof FormData)) {
body = JSON.stringify(data);
if (!headers['Content-Type']) {
xhr.setRequestHeader('Content-Type', 'application/json');
}
}
xhr.send(body);
});
}
// 使用
ajax({ url: '/api/users', method: 'GET' })
.then(data => console.log(data))
.catch(err => console.error(err));