話很少說,直接上代碼javascript
/* * 支持的參數配置項 * url * method:'GET' * data:null * dataType:'json' * async:true * cache:true * success:null * error:null * headers:null * timeout:null */
~ function () {
function ajax(options) {
return new init(options);
}
/* ==AJAX處理的核心== */
let regGET = /^(GET|DELETE|HEAD|OPTIONS)$/i;
let defaults = {
url: '', //=>請求的API接口地址
method: 'GET', //=>請求方式 GET/POST/DELETE/PUT/HEAD/OPTIONS
data: null, //=>傳遞給服務器的信息:支持格式STRING和OBJECT,若是是OBJECT,咱們須要把其處理爲x-www-form-urlencoded格式;GET請求是把信息做爲問號參數傳遞給服務器,POST請求是放到請求主體中傳遞給服務器;
dataType: 'JSON', //=>把服務器返回結果處理成爲對應的格式 JSON/TEXT/XML
async: true, //=>是否異步請求
cache: true, //=>只對GET請求有做用:設置爲FALSE,在URL的末尾加隨機數來清除緩存
timeout: null, //=>超時時間
headers: null, //=>設置請求頭信息(請求頭信息不能是中文,因此咱們須要爲其編碼)
success: null, //=>從服務器獲取成功後執行 把獲取的結果、狀態信息、XHR傳遞給它
error: null //=>獲取失敗後執行 把錯誤信息傳遞給它
};
function init(options = {}) {
//=>參數初始化:把傳遞的配置項替換默認的配置項
this.options = Object.assign(defaults, options);
this.xhr = null;
this.send();
}
ajax.prototype = {
constructor: ajax,
version: 1.0,
//=>發送AJAX請求
send() {
let xhr = null,
{
url,
method,
async,
data,
cache,
timeout,
dataType,
headers,
success,
error
} = this.options;
this.xhr = xhr = new XMLHttpRequest;
//=>處理DATA:若是是GET請求把處理後的DATA放在URL末尾傳遞給服務器
data = this.handleData();
if (data !== null && regGET.test(method)) {
url += `${this.checkASK(url)}${data}`;
data = null;
}
//=>處理CACHE:若是是GET而且CACHE是FALSE須要清除緩存
if (cache === false && regGET.test(method)) {
url += `${this.checkASK(url)}_=${Math.random()}`;
}
xhr.open(method, url, async);
//=>超時處理
timeout !== null ? xhr.timeout = timeout : null;
//=>設置請求頭信息
if (Object.prototype.toString.call(headers) === "[object Object]") {
for (let key in headers) {
if (!headers.hasOwnProperty(key)) break;
xhr.setRequestHeader(key, encodeURIComponent(headers[key]));
}
}
xhr.onreadystatechange = () => {
let {
status,
statusText,
readyState: state,
responseText,
responseXML
} = xhr;
if (/^(2|3)\d{2}$/.test(status)) {
//=>成功
if (state === 4) {
switch (dataType.toUpperCase()) {
case 'JSON':
responseText = JSON.parse(responseText);
break;
case 'XML':
responseText = responseXML;
break;
}
success && success(responseText, statusText, xhr);
}
return;
}
//=>失敗的
typeof error === "function" ? error(statusText, xhr) : null;
}
xhr.send(data);
},
//=>關於DATA參數的處理
handleData() {
let {
data
} = this.options;
if (data === null || typeof data === "string") return data;
//=>只有DATA是一個對象,咱們須要把它變爲xxx=xxx&xxx=xxx這種格式字符串
let str = ``;
for (let key in data) {
if (!data.hasOwnProperty(key)) break;
str += `${key}=${data[key]}&`;
}
str = str.substring(0, str.length - 1);
return str;
},
//=>檢測URL中是否存在問號
checkASK(url) {
return url.indexOf('?') === -1 ? '?' : '&';
}
};
init.prototype = ajax.prototype;
window._ajax = ajax;
}();
複製代碼