发送原生ajax请求分为以下几个步骤
- 实例化
XMLHttpRequest
对象获取xhr
对象 - 调用
xhr
对象的open
方法。open方法接受3个参数,请求方法(get或者post), 请求url(get请求的内容会拼接在url上面), 请求是否异步(99%的情况下我们会选择异步); - 调用
xhr
对象的send
方法,其中get请求无需传参,对于post请求需要传参 - 监听
xhr
对象onreadystatechange
回调函数,如果readyState为4(表示响应内容解析完成,可以在客户端调用
)。然后根据xhr
对象上的status
来判断当前请求是成功还是失败。status对应的是http code
const GET = "GET";
const POST = "POST";
const noop = () => {};
class Ajax {
constructor() {
// IE6以下不支持XMLHttpRequest,需要实例化ActiveXObject对象
// 现在基本没有公司需要考虑IE6以下的版本,所以这里基本可以忽略ActiveXObject这种情况
this.xhr = XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject("Microsoft.XMLHTTP");
}
/**
* 格式化数据
* {name: 'aa', age: 10} => name=aa&age=10
*/
formatData(data = {}) {
const arr = [];
for (let key in data) {
arr.push(encodeURIComponent(key) + "=" + data[key]);
}
return arr.join("&");
}
/**
* 发送请求,分为GET请求和POST请求
*/
request(options = {}) {
const self = this;
this.data = this.formatData(options.data);
this.type = (options.type || GET).toUpperCase();
this.url = options.url;
if (!this.url) {
throw new Error("ajax url is required.");
}
this.success = options.success || noop;
this.error = options.error || noop;
if (this.type === GET) {
this.xhr.open(this.type, this.url + "?" + this.data, true);
this.xhr.send();
} else if (this.type === POST) {
this.xhr.open(this.type, this.url, true);
this.xhr.setRequestHeader(
"Content-Type",
"application/x-www-form-urlencoded"
);
this.xhr.send(this.data);
}
this.xhr.onreadystatechange = function () {
if (self.xhr.readyState === 4) {
// 200-请求成功
// 204-请求成功,但是没有资源返回
// 206-请求成功,部分返回
if ([200, 204, 206].indexOf(self.xhr.status) > -1) {
const result = self.xhr.responseText;
typeof self.success === "function" &&
self.success.call(self.xhr, result);
} else {
const error = self.xhr.responseText;
typeof self.error === "function" && self.error.call(self.xhr, error);
}
}
};
}
}