框架基本结构
- 声明一个立即执行函数,整体逻辑放在立即执行函数中
- 设置默认配置项
- 设置核心方法(GET,POST)
(function anonymous(window) {
let _default = {
method: "GET",
url: "",
baseURL: "",
headers: {},
dataType: "JSON",
data: null,
params: null,
cache: true,
};
let ajaxPromise = function ajaxPromise() {};
ajaxPromise.get = function (url, options) {};
ajaxPromise.post = function (url, data, options) {};
ajaxPromise.defaults = _default;
window.ajaxPromise = ajaxPromise;
})(window);
设计AJAX请求
- 基于promise发送AJAX
- 创建
XMLHttpRequest
发送请求 - 对
GET
和POST
进行分别处理
let ajaxPromise = function ajaxPromise(options) {
let {
url,
baseURL,
method,
data,
params,
dataType,
headers,
cache,
} = options;
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open(method, baseURL + url);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (/^(2|3)\d{2}$/.test(xhr.status)) {
let result = xhr.responseText;
dataType = dataType.toUpperCase();
switch (dataType) {
case "JSON":
result = JSON.parse(result);
break;
case "XML":
result = xhr.responseXML;
break;
}
resolve(result, xhr);
return;
}
reject(xhr.statusText, xhr);
}
};
xhr.send(data);
});
};
封装方GET和POST
['get', 'delete', 'head', 'options'].forEach(item => {
ajaxPromise[item] = function anonymous(url, options = {}) {
options = {
..._default,
...options,
url: url,
method: item.toUpperCase()/
};
return ajaxPromise(options);
};
});
['post', 'put', 'patch'].forEach(item => {
ajaxPromise[item] = function anonymous(url, data = {}, options = {}) {
options = {
..._default,
...options,
url: url,
method: item.toUpperCase(),
data: data
};
return ajaxPromise(options);
};
});
完整案例代码
(function anonymous(window) {
let _default = {
method: "GET",
url: "",
baseURL: "",
headers: {},
dataType: "JSON",
data: null,
params: null,
cache: true,
};
let ajaxPromise = function ajaxPromise(options) {
let {
url,
baseURL,
method,
data,
dataType,
headers,
cache,
params,
} = options;
if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)) {
if (params) {
url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`;
}
if (cache === false) {
url += `${ajaxPromise.check(url)}_=${+new Date()}`;
}
data = null;
} else {
if (data) {
data = ajaxPromise.formatData(data);
}
}
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open(method, `${baseURL}${url}`);
if (headers !== null && typeof headers === "object") {
for (let attr in headers) {
if (headers.hasOwnProperty(attr)) {
let val = headers[attr];
if (/[\u4e00-\u9fa5]/.test(val)) {
val = encodeURIComponent(val);
}
xhr.setRequestHeader(attr, val);
}
}
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (/^(2|3)\d{2}$/.test(xhr.status)) {
let result = xhr.responseText;
dataType = dataType.toUpperCase();
dataType === "JSON"
? (result = JSON.parse(result))
: dataType === "XML"
? (result = xhr.responseXML)
: null;
resolve(result);
return;
}
reject(xhr.statusText);
}
};
xhr.send(data);
});
};
ajaxPromise.defaults = _default;
ajaxPromise.formatData = function formatData(obj) {
let str = ``;
for (let attr in obj) {
if (obj.hasOwnProperty(attr)) {
str += `${attr}=${obj[attr]}&`;
}
}
return str.substring(0, str.length - 1);
};
ajaxPromise.check = function check(url) {
return url.indexOf("?") > -1 ? "&" : "?";
};
["get", "delete", "head", "options"].forEach((item) => {
ajaxPromise[item] = function anonymous(url, options = {}) {
options = {
..._default,
...options,
url: url,
method: item.toUpperCase(),
};
return ajaxPromise(options);
};
});
["post", "put", "patch"].forEach((item) => {
ajaxPromise[item] = function anonymous(url, data = {}, options = {}) {
options = {
..._default,
...options,
url: url,
method: item.toUpperCase(),
data: data,
};
return ajaxPromise(options);
};
});
window.ajaxPromise = ajaxPromise;
})(window);