首先,定义传入 ajax函数的默认参数
var ajaxOptions = {
url: '#', url地址,默认"#"
method: 'GET', 请求方法,仅支持GET,POST,默认GET
async: true, 是否异步,默认true
timeout: 0 请求时限,超时将在promise中调用reject函数
data: null, 发送的数据,该函数不支持处理数据,将会直接发送
dataType: 'text', 接受的数据的类型,默认为text
headers: {} 一个对象,包含请求头信息
onprogress: function (){}, 处理onprogress的函数
ouploadprogress: function() {}, 处理.upload.onprogress的函数
xhr: null 允许在函数外部创建xhr对象传入,但必须不能是使用过的
}
/**
* ajax函数,返回一个promise对象
* @return {Promise}
* 该函数注册xhr.onloadend回调函数,判断xhr.status是否属于 [200,300)&&304 ,
* 如果属于则promise引发resolve状态,允许拿到xhr对象
* 如果不属于,或已经引发了ontimeout,onabort,则引发reject状态,也允许拿到xhr对象
*/
function ajax(optionsOverride) {
// 将传入的参数与默认设置合并
var options = {};
for (var k in ajaxOptions) {
options[k] = optionsOverride[k] || ajaxOptions[k];
}
options.async = options.async === false ? false : true;
var xhr = options.xhr = options.xhr || new XMLHttpRequest();
return new Promise(function (resolve, reject) {
xhr.open(options.method, options.url, options.async);
xhr.timeout = options.timeout;
//设置请求头
for (var k in options.headers) {
xhr.setRuquestHeader(k, options.headers[k]);
}
// 注册xhr对象事件
xhr.onprogress = options.onprogress;
xhr.upload.onprogress = options.onuploadprogress;
xhr.responseType = options.dataType;
xhr.onabort = function () {
reject(new Error({
errorType: 'abort_error',
xhr: xhr
}));
}
xhr.ontimeout = function () {
reject({
errorType: 'timeout_error',
xhr: xhr
});
}
xhr.onerror = function () {
reject({
errorType: 'onerror',
xhr: xhr
})
}
xhr.onloadend = function () {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)
resolve(xhr);
else
reject({
errorType: 'status_error',
xhr: xhr
})
}
try {
xhr.send(options.data);
}
catch (e) {
reject({
errorType: 'send_error',
error: e
});
}
})
}
使用方式如下:
ajax({
url: 'http://localhost:8080/dy',
async: true,
onprogress: function (e) {
console.log(e.position/e.total);
},
dataType:'text/json'
})
.then(function (xhr) { console.log(xhr.response.name); },
function (e) { console.log('失败回调') })