AJAX = new (function AJAX() { function newXHR() { return !!self.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); } function serialize(obj, prefix) { var str = []; for (var p in obj) { if (obj.hasOwnProperty(p)) { var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p]; str.push(typeof v == "object" ? serialize(v, k) : encodeURIComponent(k) + "=" + encodeURIComponent(v)); } } return str.join("&"); } function decodeResponse(type, response) { try { switch (type) { case "application/json": return JSON.parse(response); default: return response; } } catch(e) { } return response; } function doReject(strict, result){ return !!strict ? Promise.reject(result) : Promise.resolve(result); } function doRequest(url, method, params, strict) { return new Promise(function(resolve, reject) { try { if (typeof url != 'string') { return doReject(strict, { success: false, response: 'url parameter must be string', status: 0 }).then(resolve, reject); } if (typeof method != 'string') { return doReject(strict, { success: false, response: 'method parameter must be string', status: 0 }).then(resolve, reject); } method = method.toUpperCase(); var xhr = newXHR(); xhr.onload = function(e) { if (e.target.status == 200) { var response = decodeResponse(e.target.getResponseHeader("Content-Type"), e.target.response); resolve({ success: true, response: response, status: e.target.status }); } else { var statusText = e.target.statusText; if (!statusText.length) statusText = "unexpected error"; doReject(strict, { success: false, response: statusText, status: e.target.status }).then(resolve, reject); } } xhr.onerror = function(e) { var statusText = e.target.statusText; if (!statusText.length) statusText = "unexpected error"; doReject(strict, { success: false, response: statusText, status: e.target.status }).then(resolve, reject); } xhr.onabort = function(e) { doReject(strict, { success: false, response: 'download aborted', status: 0 }).then(resolve, reject); } params = typeof params == 'object' ? serialize(params) : ''; if (method === 'GET') { if (!!params.length) params = "?" + params; xhr.open(method, url+params); xhr.send(); } else { xhr.open(method, url); xhr.send(!!params.length ? params : undefined); } } catch(e) { doReject(strict, { success: false, response: e.message, status: 0 }).then(resolve, reject); } }); } this.request = function(requests, strict) { if (typeof strict != 'boolean') strict = true; try { if (typeof requests == 'string') { return doRequest(requests, 'GET', [], strict); } else { if (typeof requests == 'object') { if (Array.isArray(requests)) { var proms = []; for (var i = 0; i < requests.length; ++i) proms.push(this.request(requests[i], strict)); return Promise.all(proms); } else { return doRequest(requests.url, requests.method, requests.params, strict); } } throw new Error('wrong type (string/array/dict expected, '+(typeof requests)+' detected)'); } } catch(e) { return doReject(strict, { success: false, response: e.message, status: 0 }); } } return Object.freeze(this); });