Files
2019-01-25 17:01:52 +08:00

149 lines
4.3 KiB
JavaScript

var EventEmitter = require('events').EventEmitter,
queryString = require('query-string');
function tryParseJson(data){
try{
return JSON.parse(data);
}catch(error){
return error;
}
}
function timeout(){
this.request.abort();
this.emit('timeout');
}
function Ajax(settings){
var queryStringData,
ajax = this;
if(typeof settings === 'string'){
settings = {
url: settings
};
}
if(typeof settings !== 'object'){
settings = {};
}
ajax.settings = settings;
ajax.request = new XMLHttpRequest();
ajax.settings.method = ajax.settings.method || 'get';
if(ajax.settings.cors && !'withCredentials' in ajax.request){
if (typeof XDomainRequest !== 'undefined') {
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
ajax.request = new XDomainRequest();
} else {
// Otherwise, CORS is not supported by the browser.
ajax.emit('error', new Error('Cors is not supported by this browser'));
}
}
if(ajax.settings.cache === false){
ajax.settings.data = ajax.settings.data || {};
ajax.settings.data._ = new Date().getTime();
}
if(ajax.settings.method.toLowerCase() === 'get' && typeof ajax.settings.data === 'object'){
var urlParts = ajax.settings.url.split('?');
queryStringData = queryString.parse(urlParts[1]);
for(var key in ajax.settings.data){
queryStringData[key] = ajax.settings.data[key];
}
var parsedQueryStringData = queryString.stringify(queryStringData);
ajax.settings.url = urlParts[0] + (parsedQueryStringData ? '?' + parsedQueryStringData : '');
ajax.settings.data = null;
}
ajax.request.addEventListener('progress', function(event){
ajax.emit('progress', event);
}, false);
ajax.request.addEventListener('load', function(event){
var data = event.target.responseText;
if(ajax.settings.dataType && ajax.settings.dataType.toLowerCase() === 'json'){
if(data === ''){
data = undefined;
}else{
data = tryParseJson(data);
if(data instanceof Error){
ajax.emit('error', event, data);
return;
}
}
}
if(event.target.status >= 400){
ajax.emit('error', event, data);
} else {
ajax.emit('success', event, data);
}
}, false);
ajax.request.addEventListener('error', function(event){
ajax.emit('error', event);
}, false);
ajax.request.addEventListener('abort', function(event){
ajax.emit('error', event, new Error('Connection Aborted'));
ajax.emit('abort', event);
}, false);
ajax.request.addEventListener('loadend', function(event){
clearTimeout(ajax._requestTimeout);
ajax.emit('complete', event);
}, false);
ajax.request.open(ajax.settings.method || 'get', ajax.settings.url, true);
if(ajax.settings.cors && 'withCredentials' in ajax.request) {
ajax.request.withCredentials = !!settings.withCredentials;
}
// Set default headers
if(ajax.settings.contentType !== false){
ajax.request.setRequestHeader('Content-Type', ajax.settings.contentType || 'application/json; charset=utf-8');
}
if(ajax.settings.requestedWith !== false) {
ajax.request.setRequestHeader('X-Requested-With', ajax.settings.requestedWith || 'XMLHttpRequest');
}
if(ajax.settings.auth){
ajax.request.setRequestHeader('Authorization', ajax.settings.auth);
}
// Set custom headers
for(var headerKey in ajax.settings.headers){
ajax.request.setRequestHeader(headerKey, ajax.settings.headers[headerKey]);
}
if(ajax.settings.processData !== false && ajax.settings.dataType === 'json'){
ajax.settings.data = JSON.stringify(ajax.settings.data);
}
}
Ajax.prototype = Object.create(EventEmitter.prototype);
Ajax.prototype.send = function(){
var ajax = this;
ajax._requestTimeout = setTimeout(
function(){
timeout.apply(ajax, []);
},
ajax.settings.timeout || 120000
);
ajax.request.send(ajax.settings.data && ajax.settings.data);
};
module.exports = Ajax;