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;