Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- <<Asynchronous Javascript And Xml>>-контроллер
- #ajax
- */
- var ajax = {
- urlonly: !('FormData' in window),
- /*
- E_CONNECT: 0,
- E_ABORTED: -1,
- E_TIMEOUT: -2,
- */
- get: function(url, opts) {
- opts.method = 'GET';
- return ajax.request(url, opts);
- },
- post: function(url, opts) {
- opts.method = 'POST';
- return ajax.request(url, opts);
- },
- buildQuery: function(query) {
- if (ajax.urlonly) {
- return ajax.urlencode(query);
- }
- return ajax.formData(query);
- },
- urlencode: function(query) {
- if (typeof query == 'string') {
- return query;
- }
- var s = [],
- add = function( key, value ) {
- s.push(encodeURIComponent( key ) + "=" + encodeURIComponent( value ));
- },
- buildParams = function ( prefix, obj, add ) {
- if ( Array.isArray( obj ) ) {
- // Serialize array item.
- forEach( obj, function( i, v ) {
- buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, add );
- });
- return;
- }
- if (typeof obj == 'object' && obj) {
- // Serialize object item.
- for ( var name in obj ) {
- buildParams( prefix + "[" + name + "]", obj[ name ], add );
- }
- return;
- }
- // Serialize scalar item.
- add( prefix, obj );
- };
- for ( var prefix in query ) {
- buildParams( prefix, query[ prefix ], add );
- }
- // Return the resulting serialization
- return s.join('&');
- },
- formData: function(query) {
- if (query instanceof FormData) {
- return query;
- }
- var data = new FormData;
- // each(query, data.append.bind(data));
- for (var name in query) {
- data.append(name, query[name]);
- }
- return data;
- },
- createResponse: function(xhr, other) {
- if (!other) {
- other = {};
- }
- var response = {
- url: xhr.responseURL || xhr.getResponseHeader('Location') || '',
- status: other.status == null ? xhr.status : other.status,
- statusText: other.statusText ? other.statusText : xhr.statusText,
- text: xhr.status == 204 ? '' : xhr.responseText,
- headers: (function(xhr) {
- var headers = {};
- forEach(
- xhr.getAllResponseHeaders().split('\r\n').filter(function(v) { return v !== ''; }),
- function(i, header) {
- var parsed = header.split(': ');
- headers[parsed[0]] = parsed[0] == 'Date' ? [parsed[1]] : parsed[1].split(/, ?/);
- }
- );
- return {
- has: function(name) {
- return name in headers;
- },
- get: function(name) {
- return headers[name] ? headers[name][0] : null;
- },
- getAll: function(name) {
- return headers[name] || null;
- },
- set: function(name, value) {
- headers[name] = Array.isArray(value) ? value : [value];
- },
- append: function(name, value) {
- if (!headers[name]) {
- headers[name] = [];
- }
- headers[name].push(value);
- },
- delete: function(name) {
- delete headers[name];
- }
- };
- })(xhr),
- };
- if (xhr.responseText && (xhr.getResponseHeader('Content-Type') || '').startsWith('application/json')) {
- try {
- response.json = JSON.parse(xhr.responseText);
- } catch (e) {};
- }
- /*
- else if (xhr.responseXML) {
- response.xml = responseXML;
- }
- */
- return response;
- },
- request: function(url, opts) {
- if (!opts && typeof url == 'object') {
- opts = url;
- url = '';
- } else if (url == undefined) {
- url = '';
- }
- //opts = ajax.createRequest(url, opts);
- opts = extend({
- method: 'GET',
- //params: null, // params - для параметров URL,
- body: null, // body - для тела запроса
- timeout: 0 // после timeout вызывается onError со статусом -1
- /*
- onLoad: null,
- onError: null,
- onDone: null,
- showProgress: null,
- hideProgress: null,
- headers: {
- 'X-Requested-With': 'XMLHttpRequest'
- }
- */
- }, opts || {});
- if (opts.showProgress) {
- opts.showProgress();
- }
- opts.method = opts.method.toUpperCase();
- /*
- if (opts.data) {
- if ( ['OPTIONS', 'HEAD', 'GET', 'DELETE'].includes(opts.method) ) {
- opts.params = opta.data;
- } else {
- opts.body = opts.data;
- }
- delete opts.data;
- }
- */
- if (opts.params) {
- url += (url.includes('?') ? '&' : '?') + ajax.urlencode(opts.params);
- }
- // TypeError: HEAD or GET Request cannot have a body. (c) ES6 fetch
- if ( opts.body && !['OPTIONS', 'HEAD', 'GET', 'DELETE'].includes(opts.method) ) {
- opts.body = ajax.buildQuery(opts.body);
- } else {
- opts.body = null;
- }
- /*
- if (!opts.headers['Content-Type'] && opts.body) {
- opts.headers['Content-Type'] = ajax.urlonly ? 'application/x-www-form-urlencoded' : 'multipart/form-data';
- }
- */
- var done = function(error, other) {
- var response = ajax.createResponse(xhr, other); // это может быть долго, поэтому сначала создаём response..
- if (opts.hideProgress) opts.hideProgress(); // .., а потом убираем прогресс
- if (!error && (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304)) {
- if (opts.onLoad) opts.onLoad(response);
- } else {
- if (opts.onError) opts.onError(response);
- }
- if (opts.onDone) opts.onDone(response);
- };
- var xhr = new XMLHttpRequest;
- xhr.onload = done.pbind(false);
- xhr.onerror = done.pbind(true, { status: 0, statusText: 'Connection Error' });
- xhr.onabort = done.pbind(true, { status: -1, statusText: 'Request Aborted' });
- if (opts.timeout) {
- xhr.timeout = opts.timeout;
- xhr.ontimeout = done.pbind(true, { status: -2, statusText: 'Request Timeout' });
- }
- if (opts.progressLine) {
- var lastState = -1;
- xhr.onreadystatechange = (function(progressLine) {
- if (lastState != xhr.readyState) {
- animate(progressLine, { width: progressLine.parentNode.offsetWidth / 4 * xhr.readyState }, 100); // в % от длинны
- }
- lastState = xhr.readyState;
- }).pbind(opts.progressLine);
- }
- xhr.open(opts.method, url, true); // нельзя отправлять Headers раньше .open(...)
- if (opts.headers) {
- for (var key in opts.headers) {
- xhr.setRequestHeader(key, opts.headers[key]);
- }
- }
- xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
- if (opts.data && ajax.urlonly && !(opts.headers && opts.headers['Content-Type'])) {
- xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- }
- xhr.send(opts.body);
- return xhr;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement