Skip to content

Instantly share code, notes, and snippets.

@warmrobot
Forked from RubaXa/xhr.js
Last active May 25, 2017 13:07
Show Gist options
  • Select an option

  • Save warmrobot/db42375c7af34de193ed3d4b5aa1d4ae to your computer and use it in GitHub Desktop.

Select an option

Save warmrobot/db42375c7af34de193ed3d4b5aa1d4ae to your computer and use it in GitHub Desktop.
Микро обертка для выполенения XHR-запросов
/**
* Микро обертка для выполенения XHR-запросов
* @namepace window.xhr
*/
(function (global, factory) {
if (typeof define === 'function' && define.amd) {
define(factory);
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
global.xhr = factory();
}
})(this, function () {
'use strict';
var noop = function () {};
var xhr = {
version: '0.3.1',
/**
* Вид запросов по умолчанию
* @type {boolean}
*/
async: true,
/**
* Центральная обработка запросов
* @type {Function}
*/
oncomplete: null,
/**
* Загрузить ресурс
* @param {string} url
* @param {Object|Function} [options]
* @param {Function} [callback]
*/
load: function (url, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
var req,
async,
startTime = new Date(),
complete = function (err) {
if (err || req.readyState === 4) {
complete = noop; // затираем пустышкой
err = err || (req.status !== 200 && req.status !== 201);
req.duration = new Date() - startTime;
req.onreadystatechange = null;
callback && callback(err, req);
xhr.oncomplete && xhr.oncomplete(err, req);
}
};
options = options || {};
async = options.async === void 0 ? this.async : options.async;
try {
req = new global.XMLHttpRequest();
}
catch (err) {
try {
req = new global.ActiveXObject("Msxml2.XMLHTTP");
} catch (err) {
try {
req = new global.ActiveXObject("Microsoft.XMLHTTP");
} catch (err) {
req = {readyState: 4, status: -1};
req.open = req.send = noop;
}
}
}
req.url = url;
req.onerror = function (evt) {
req.onerror = null;
complete(evt);
};
try {
req.open(options.type || 'GET', url, async);
req.send(null);
if (async) {
req.onreadystatechange = function () {
complete();
};
}
else {
complete();
}
} catch (err) {
complete(err);
}
},
/**
* Загрузка ресурса с возможность повтора и eval для js
* @param {string} url
* @param {function} [oncomplete]
* @param {number} [attempt]
* @return {XMLHttpRequest}
*/
fetchResource: function (url, oncomplete, attempt) {
var fetchResource = xhr.fetchResource;
var filename = url.split('/').pop().replace(/(\.\w+)(\?.*)?$/, '$1');
attempt = attempt | 0;
return xhr.load(url, function (err, xhr) {
var evalTime = new Date();
xhr.error = err;
xhr.attempt = attempt;
xhr.filename = filename;
xhr.filesize = (xhr.responseText || '').length;
xhr.evalDuration = 0;
try {
// Eval source
if (!err && /\.js$/.test(filename)) {
eval.call(window, xhr.responseText + '\n//@ sourceURL=' + url);
}
} catch (error) {
err = error;
xhr.evalError = error;
} finally {
xhr.evalDuration = new Date() - evalTime;
}
if (err) {
fetchResource.onerror && fetchResource.onerror(err, xhr);
}
if (err && (attempt < fetchResource.maxAttempts)) {
// Retry
attempt++;
fetchResource.onretry && fetchResource.onretry(err, xhr);
fetchResource(url, oncomplete, attempt);
}
else {
oncomplete && oncomplete(err, xhr);
fetchResource.oncomplete && fetchResource.oncomplete(err, xhr);
}
});
},
patchRequireJS: function (require) {
require.load = function (context, moduleName, url) {
xhr.fetchResource(url, function () {
// todo: catch error;
context.completeLoad(moduleName);
});
};
}
};
/**
* Последовательная загрузка ресурсов
* @param {string[]} urls
* @param {function} [oncomplete]
*/
xhr.fetchResource.series = function fetchResourceSeries(urls, oncomplete) {
var queue = urls.slice(0); // clone
(function _fetchNext() {
var url = queue.shift();
if (url) {
xhr.fetchResource(url, function (err) {
if (err) {
oncomplete(err);
} else {
_fetchNext();
}
});
} else {
oncomplete();
}
})();
};
/**
* Масимальное кол-во попыток при загрузке ресурсов
* @type {number}
*/
xhr.fetchResource.maxAttempts = 2;
return xhr
});
(function(k){var l=function(){},g={version:"0.3.1",async:!0,oncomplete:null,load:function(f,b,d){"function"===typeof b&&(d=b,b={});var a,h,e=new Date,c=function(b){if(b||4===a.readyState)c=l,b=b||200!==a.status&&201!==a.status,a.duration=new Date-e,a.onreadystatechange=null,d&&d(b,a),g.oncomplete&&g.oncomplete(b,a)};b=b||{};h=void 0===b.async?this.async:b.async;try{a=new k.XMLHttpRequest}catch(m){try{a=new k.ActiveXObject("Msxml2.XMLHTTP")}catch(n){try{a=new k.ActiveXObject("Microsoft.XMLHTTP")}catch(p){a=
{readyState:4,status:-1},a.open=a.send=l}}}a.url=f;a.onerror=function(b){a.onerror=null;c(b)};try{a.open(b.type||"GET",f,h),a.send(null),h?a.onreadystatechange=function(){c()}:c()}catch(m){c(m)}},fetchResource:function(f,b,d){var a=g.fetchResource,h=f.split("/").pop().replace(/(\.\w+)(\?.*)?$/,"$1");d|=0;return g.load(f,function(e,c){var g=new Date;c.error=e;c.attempt=d;c.filename=h;c.filesize=(c.responseText||"").length;c.evalDuration=0;try{!e&&/\.js$/.test(h)&&eval.call(window,c.responseText+"\n//@ sourceURL="+
f)}catch(k){e=k,c.evalError=k}finally{c.evalDuration=new Date-g}e&&a.onerror&&a.onerror(e,c);e&&d<a.maxAttempts?(d++,a.onretry&&a.onretry(e,c),a(f,b,d)):(b&&b(e,c),a.oncomplete&&a.oncomplete(e,c))})},patchRequireJS:function(f){f.load=function(b,d,a){g.fetchResource(a,function(){b.completeLoad(d)})}}};g.fetchResource.series=function(f,b){var d=f.slice(0);(function h(){var e=d.shift();e?g.fetchResource(e,function(c){c?b(c):h()}):b()})()};g.fetchResource.maxAttempts=2;k.xhr=g})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment