forty2
Version:
Collection of libraries that answer the ultimate question to the meaning of life
223 lines (184 loc) • 6.99 kB
JavaScript
import { browser as browser } from './browser.js';
import * as defer from './promise.js';
import { extend as extend, tryCatch as tryCatch } from './utils.js'
const allowedLegacyXdomain = ['GET', 'POST'],
allowedRequests = ['GET', 'POST', 'PUT', 'DELETE'],
http = (params) => {
let httpResponse = defer.promise();
extend(params).with({
async:true
});
params.send = (params.send != null && params.send !== '') ? JSON.stringify(params.send) : null;
params.type = (params.type) ? params.type.toUpperCase() : 'GET'
if(allowedRequests.indexOf(params.type) === -1) {
httpResponse.reject('Invalid request type: '+ params.type);
return httpResponse;
}
if(browser().legacyIe && !params.withCredentials && params.async === true && !isSameDomain(params.url)) {
return legacyXdomain(params, httpResponse);
}
else {
return modernXdomain(params, httpResponse);
}
},
isSameDomain = (url) => {
return url.indexOf(window.location.protocol +'//'+ window.location.host) === 0;
},
modernXdomain = (data, httpResponse) => {
tryCatch({
'try':() => {
let xhr = new XMLHttpRequest();
addDataProperties(data, xhr);
xhr.open(data.type, data.url, data.async);
if(xhr.addEventListener) {
xhr.addEventListener('progress', function(event) {
if (event.lengthComputable && window.ruf) {
ruf(window).trigger('ajaxProgress', {
event:event,
url:data.url,
data:data,
promise:httpResponse
});
}
}, false);
}
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
let result = processResponse(xhr);
if(data.responseHeader) {
let headers = Object.keys(data.responseHeader);
headers.map(function(header) {
if(headers[header] === true) {
data.responseHeader[header] = xhr.getResponseHeader(header);
}
});
}
if(data.responseHeaders === true) {
data.responseHeaders = xhr.getAllResponseHeaders();
}
if(xhr.status >= 200 && xhr.status < 400) {
httpResponse.resolve(result);
}
else {
httpResponse.reject((result != null && result !== '') ? 'XMLHttpRequest rejected: '+ result : 'XMLHttpRequest rejected');
}
}
};
addRequestHeaders.apply(this, [data, xhr]);
xhr.send(data.send);
},
'catch':(err) => {
console.error(err);
httpResponse.reject('XMLHttpRequest rejected: '+ err);
}
});
return httpResponse;
},
legacyXdomain = function http(data, httpResponse) {
if(allowedLegacyXdomain.indexOf(data.type) > -1) {
return modernXdomain(data, httpResponse);
}
let xhr = new window.XDomainRequest();
addDataProperties(data, xhr);
xhr.onerror = function(err) {
httpResponse.reject('XMLHttpRequest rejected: '+ err);
};
if(xhr.onprogress && window.ruf) {
xhr.onprogress = function(event) {
ruf(window).trigger('ajaxProgress', {
event:event,
url:url,
data:data,
promise:httpResponse
});
};
}
xhr.onload = function () {
let result = processResponse(xhr);
httpResponse.resolve(result);
};
xhr.timeout = function() {
httpResponse.reject('XMLHttpRequest timed out');
};
xhr.open(data.type, data.url);
addRequestHeaders(data, xhr);
xhr.send(data.send);
return httpResponse;
};
function addDataProperties(data, xhr) {
let properties = Object.keys(data);
properties.map(function(property) {
if(property !== 'requestHeader' && property !== 'send') {
xhr[property] = data[property];
}
});
}
function addRequestHeaders(data, xhr) {
if(data.requestHeader && data.type === 'POST') {
let headers = Object.keys(data.requestHeader);
headers.map(function(header) {
xhr.setRequestHeader(header, data.requestHeader[header]);
});
}
}
function processResponse(xhr) {
let response = (xhr.responseXML != null) ?
xmlToJson(xhr.responseXML.documentElement) : otherToJson(xhr.responseText);
return response || xhr.responseText;
}
function otherToJson(data) {
let returnObject = null,
looseParse = function() {
tryCatch({
'try':() => {
returnObject = (new Function('return '+ data)());
},
'catch':(err) => {
returnObject = data;
}
});
};
looseParse();
return returnObject;
}
function xmlToJson(xml) {
let returnObject = {};
if(!xml) {
return xml;
}
/* element node */
if(xml.nodeType == 1) {
/* do attributes */
if (xml.attributes.length > 0) {
returnObject["@attributes"] = {};
for (let j = 0; j < xml.attributes.length; j++) {
let attribute = xml.attributes.item(j);
returnObject["@attributes"][attribute.nodeName] = attribute.nodeValue;
}
}
}
/* text node */
else if (xml.nodeType == 3) {
returnObject = xml.nodeValue;
}
else {}
/* do children */
if (xml.hasChildNodes()) {
for(let i = 0; i < xml.childNodes.length; i++) {
let item = xml.childNodes.item(i);
let nodeName = item.nodeName;
if (typeof(returnObject[nodeName]) == "undefined") {
returnObject[nodeName] = xmlToJson(item);
} else {
if (typeof(returnObject[nodeName].push) == "undefined") {
let old = returnObject[nodeName];
returnObject[nodeName] = [];
returnObject[nodeName].push(old);
}
returnObject[nodeName].push(xmlToJson(item));
}
}
}
return returnObject;
}
export { http };