用TypeScript简单的封装了一下ajax,类似Jqurey
代码如下:
let $ = {
createXHR: function (): XMLHttpRequest {
if (window.XMLHttpRequest) {
// 若浏览器支持,则创建XMLHttpRequest对象
return new XMLHttpRequest();
} else {
// 若不支持,则创建ActiveXobject对象
return new ActiveXObject("Microsoft.XMLHTTP");
}
},
ajax: function (params: {
type: string, // 请求的类型GET或者POST
url: string, // 请求的url
data?: any, // 请求的参数
dataType?: string, // 响应内容的方式
isAsync?: boolean // 是否异步
}): Promise<any> {
// 1.初始化参数
let type = params.type.toUpperCase();
let url = params.url;
let data = params.data ? params.data : {};
let dataType = params.dataType ? params.dataType : "json";
let isAsync = params.isAsync ? params.isAsync : true;
// 2.用参数动态生成XHR对象
let xhr = this.createXHR();
let qureyStr = "";
// 拼接查询字符串
Object.keys(data).forEach(key => qureyStr += `${key}=${data[key]}&`);
qureyStr = qureyStr.slice(0, -1);
// 如果get请求就把qureyStr拼接到url后面
if (type == "GET") {
url += `?${qureyStr}`;
}
// 响应的结果通过Promise来处理
return new Promise((resolve, reject) => {
xhr.open(type, url, isAsync);
if (type == "POST") {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-rulencoded');
xhr.send(qureyStr);
} else {
xhr.send()
}
// 状态码变化的事件
xhr.onreadystatechange = function () {
// 如果已经收到全部的响应
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.readyState <= 300 || xhr.status == 304) {
let res = dataType === "json" ? JSON.parse(xhr.responseText) : xhr.responseText;
resolve(res);
} else {
reject(xhr.readyState);
}
}
}
})
}
}
其中readyState
是表示当前xhr
请求的状态
readyState | 请求的阶段 |
---|---|
0 | 还未创建请求,即未调用 open() 方法 |
1 | 已调用 open() 方法,但未发送 send() 方法 |
2 | 已调用 send() 方法,但未接收到响应 |
3 | 已接收到部分响应 |
4 | 已接收到全部的响应 |
xhr对象可以绑定一个 readystatechange
事件,每当 readyState
属性发生改变,都会触发该事件,因此,该事件在一次请求中会被多次触发。
所以,我们可以在 readystatechange
事件中判断一下 readyState
属性是否为 4
,即是否已经接收所有的响应,然后还可以再继续判断一下 status
属性,看看状态码是否为 200
,当上述都成立了,我们再去 responseText
属性中获取响应数据。
参考博客: 异步编程Ajax的详解,并对其进行封装整理