This repository has been archived by the owner on Mar 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAsynjax.es.js
401 lines (375 loc) · 16.5 KB
/
Asynjax.es.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
/*!
*
* Asynjax - Asíncrono Ajax sin jQuery
* Copyright (c) 2018 JeiHO (https://github.com/jeijei4/Asynjax)
* Licensed under MIT (http://www.opensource.org/licenses/mit-license.php)
*
* Version: 2.0.0
*
*/
var asynjax = {};
asynjax.contains = function (a, b) {
// true: si a contiene b.
return (new RegExp(b.toLowerCase(), "g")).test(a.toLowerCase());
};
asynjax.httpRequest = function () {
'use strict';
// Determine si el objeto XMLHttpRequest es compatible
// Chrome, Firefox, Opera 8.0+, Safari
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
//Compatible con el navegador IE
const versions = [
'MSXML2.XmlHttp.6.0',
'MSXML2.XmlHttp.5.0',
'MSXML2.XmlHttp.4.0',
'MSXML2.XmlHttp.3.0',
'MSXML2.XmlHttp.2.0',
'Microsoft.XmlHttp'
];
// Defina la variable local xhr y almacene el objeto ActiveXObject del navegador IE.
let xhr;
for (let i = 0; i < versions.length; i++) {
try {
xhr = new ActiveXObject(versions[i]);
break;
} catch (e) {
}
}
return xhr;
};
asynjax.param = function (xJson, prefix) {
//https://stackoverflow.com/a/1714899/9463541
var str = [], p;
for (p in xJson) {
if (xJson.hasOwnProperty(p) && xJson[p]) {
var k = prefix ? prefix + "[" + p + "]" : p,
v = xJson[p];
str.push((v !== null && typeof v === "object") ?
asynjax.param(v, k) :
encodeURIComponent(k) + "=" + encodeURIComponent(v));
}
}
return str.join("&");
};
asynjax.getFormData = function (formData) {
let r = {};
try {
formData.forEach(function (value, key) {
r[key] = value;
});
} catch (err) {
r = {};
throw new Error(err.message);
}
return r;
};
asynjax.getForm = function (xform, hideClass) {
let r = {};
try {
const elements = xform.querySelectorAll('input:not([type="radio"]):not([type="checkbox"]), input[type="checkbox"]:checked, input[type="radio"]:checked, select, textarea');
const elemLength = elements.length;
for (let i = 0; i < elemLength; ++i) {
const element = elements[i];
const tagName = elements[i].tagName.toLowerCase();
var key = element.name;
const value = element.value;
if (key) {
if ('select' === tagName && true === element.multiple) {
var selectedArray = [];
var j;
var count = 0;
const selectLength = element.options.length;
for (j = 0; j < selectLength; ++j) {
if (element.options[j].selected) {
selectedArray[count] = element.options[j].value;
++count;
}
}
if (hideClass.length === 0 || asynjax.contains(element.className, hideClass) === false) {
const optLength = selectedArray.length;
var hilera = '';
for (k = 0; k < optLength; ++k) {
if ('' !== hilera) {
hilera += ',';
}
if ('string' === typeof(selectedArray[k])) {
hilera += '"' + selectedArray[k] + '"';
} else {
hilera += selectedArray[k];
}
}
const allHilera = '"' + key + '":[' + hilera + ']';
var textObject = JSON.stringify(r);
if (textObject === '{}') {
r = JSON.parse('{' + allHilera + '}');
} else {
r = JSON.parse('{' + textObject.substring(1, textObject.length - 1) + ',' + allHilera + '}');
}
}
} else {
if (hideClass.length === 0 || asynjax.contains(element.className, hideClass) === false) {
r[key] = value;
}
}
}
}
} catch (err) {
r = {};
throw new Error(err.message);
}
return r;
};
asynjax.textError = function (xStatus, xStatusText, xResponseText) {
'use strict';
const xResponse = xResponseText.trim();
const respLower = xResponse.toLowerCase();
if (asynjax.contains(respLower, 'sesi') === true && asynjax.contains(respLower, 'expirado') === true) {
return 'La sesión ha expirado';
}
else {
let text = "";
switch (parseInt(xStatus)) {
case 0:
text = "Error de conectividad: Verificar la Red";
break;
case 400:
text = "Error de cliente: Solicitud incorrecta. [400]";
break;
case 401:
text = "Error de cliente: No autorizado, la autenticación es posible pero ha fallado o aún no se ha proporcionado. [401]";
break;
case 402:
text = "Error de cliente: Pago requerido. [402]";
break;
case 403:
text = "Error de cliente: Prohibido, el servidor se niega a responder. [403]";
break;
case 404:
text = "Error de cliente: La página solicitada no se encontró. [404]";
break;
case 405:
text = "Error de cliente: Método de solicitud no permitido. [405]";
break;
case 406:
text = "Error de cliente: La respuesta del servidor no es aceptada. [406]";
break;
case 407:
text = "Error de cliente: Debe primero autenticarse con el proxy. [407]";
break;
case 408:
text = "Error de cliente: El servidor agotó el tiempo de espera para la solicitud. [408]";
break;
case 409:
text = "Error de cliente: La solicitud no se pudo completar debido a un conflicto en la solicitud. [409]";
break;
case 410:
text = "Error de cliente: La página solicitada ya no está disponible. [410]";
break;
case 411:
text = 'Error de cliente: La "longitud del contenido" no está definida. El servidor no aceptará la solicitud sin él. [411]';
break;
case 412:
text = "Error de cliente: La condición previa dada en la solicitud es evaluada como falsa por el servidor. [412]";
break;
case 413:
text = "Error de cliente: La entidad de solicitud es demasiado grande. [413]";
break;
case 414:
text = "Error de cliente: La URL es demasiado larga. [414]";
break;
case 415:
text = "Error de cliente: El tipo de medio no es compatible con el servidor. [415]";
break;
case 416:
text = "Error de cliente: El cliente ha solicitado una parte del archivo, pero el servidor no puede suministrar esa parte. [416]";
break;
case 417:
text = "Error de cliente: El servidor no puede cumplir con los requisitos del encabezado de la solicitud. [417]";
break;
case 418:
text = "Error de cliente: Soy una tetera. Se ha intentado realizar una solicitud de café en un servidor que no es una cafetera, sino una tetera. [418]";
break;
case 421:
text = "Error de cliente: Solicitud estraviada. La solicitud se dirigió a un servidor que no es capaz de producir una respuesta. [421]";
break;
case 422:
text = "Error de cliente: La solicitud está bien construida, pero fue imposible de entender debido a errores semánticos. [422]";
break;
case 423:
text = "Error de cliente: El recurso que está siendo accedido está bloqueado. [423]";
break;
case 424:
text = "Error de cliente: Error de dependencia. Error de la solicitud debido a un fallo de una solicitud anterior. [424]";
break;
case 426:
text = "Error de cliente: Actualización obligatoria : El cliente debe cambiar a un protocolo diferente. [426]";
break;
case 428:
text = "Error de cliente: Condición previa obligatoria. El servidor de origen requiere que la solicitud sea condicional. [428]";
break;
case 429:
text = "Error de cliente: El usuario ha enviado demasiadas solicitudes en un período de tiempo determinado. [429]";
break;
case 431:
text = "Error de cliente: El servidor no puede procesar la petición porque el conjunto de las cabeceras de la petición son demasiado grandes. [431]";
break;
case 451:
text = "Error de cliente: No disponible por razones legales. [451]";
break;
case 500:
text = "Error interno del servidor : El servidor encontró una condición inesperada. [500]";
break;
case 501:
text = "Error del Servidor: El servidor no reconoce el método de solicitud o carece de la capacidad para cumplir con la solicitud. [501]";
break;
case 502:
text = "Error del Servidor: El servidor está actuando como una puerta de enlace y recibió una respuesta no válida de otro servidor. [502]";
break;
case 503:
text = "Error del Servidor: El servidor no está disponible actualmente (sobrecargado | en mantenimiento | inactivo). [503]";
break;
case 504:
text = "Error del Servidor: El servidor está actuando como una puerta de enlace y no ha recibido a tiempo una respuesta de otro servidor, por lo que no puede responder adecuadamente a la petición solicitada. [504]";
break;
case 505:
text = "Error del Servidor: El servidor no admite la versión de protocolo HTTP utilizada en la solicitud. [505]";
break;
case 506:
text = "Error del Servidor: Variación también negocia. La negociación de contenido de los resultados de petición deriva en una referencia circular. [506]";
break;
case 507:
text = "Error del Servidor: No hay suficiente espacio de almacenamiento libre. [507]";
break;
case 508:
text = "Error del Servidor: La petición no se puede procesar porque el servidor ha encontrado un bucle infinito. [508]";
break;
case 510:
text = "Error del Servidor: La petición del cliente debe añadir más extensiones para que el servidor pueda procesarla. [510]";
break;
case 511:
text = "Error del Servidor: El cliente debe autenticarse para poder realizar peticiones. [511]";
break;
default:
text = "parsererror" === xStatusText ? "Error de análisis en el JSON solicitado." : "timeout" === xStatusText ? "Error: tiempo de espera excedido." : "abort" === xStatusText ? "Petición Ajax abortada." : "Error no detectado (" + xStatus + " - " + xStatusText + "): " + xResponse;
}
return text;
}
};
asynjax.send = function (url, method, xFunction, options) {
'use strict';
let client = asynjax.httpRequest();
client.open(method, url, true, null, null);
const withOptions = ('object' === typeof options);
client.withCredentials = (true === withOptions && true === options.withCredentials); //default false;
client.ontimeout = function () {
console.error('Asynjax error: El tiempo de espera para la solicitud ' + url + ' a caducado.');
};
client.onerror = function () {
console.error('Asynjax error: ' + asynjax.textError(client.status, client.statusText, client.responseText));
};
client.onreadystatechange = function () {
if (client.readyState === 4) {
if (client.status === 200) {// 200 = OK
let responseText = client.responseText;
if (true === withOptions && true === options.asJson) {
let getData = responseText.trim();
try {
responseText = JSON.parse(getData);
} catch (e) {
try {
// Si la respuesta está en formato JSONP en lugar de JSON puro:
const fixedResponse = getData.replace(/\\'/g, "'");
responseText = JSON.parse(fixedResponse);
} catch (e) {
responseText = {};
}
}
}
xFunction(true, responseText);
} else {
// Devolución de llamada de error
xFunction(false, asynjax.textError(client.status, client.statusText, client.responseText));
}
}
};
if (true === withOptions && 'function' === typeof options.progress) {
client.upload.onprogress = function (event) {
let p = '?';
if (event.lengthComputable) {
p = Math.round((event.loaded / event.total) * 100);
}
options.progress(p);
};
}
/////////////////////////////////////////////////////////////////////////////////////
client.setRequestHeader("Cache-Control", "no-cache");
client.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
if (method === 'POST' && true === withOptions) {
if ('object' === typeof options.formData) {
client.send(options.formData);
} else {
if (options.contentType) {
client.setRequestHeader('Content-Type', options.contentType);
}
if (options.form) {
const hideClass = ('string' === typeof options.hideClass) ? options.hideClass : '';
const xForm = asynjax.getForm(options.form, hideClass);
client.send(asynjax.param(xForm));
} else {
if (null === options.params) {
client.send();
} else {
client.send(options.params);
}
}
}
} else {
client.send();
}
};
asynjax.post = function (url, options, xFunction) {
'use strict';
if ('function' === typeof options) {
//Se envía sin parámetros
asynjax.send(url, 'POST', options);
} else if ('function' === typeof xFunction) {
if ('object' === typeof options) {
// Solicitud con contentType false, sin procesamiento de datos;
if (options.contentType !== false) {
if (options.contentType && asynjax.contains(options.contentType, 'json') === true) {
if (options.params) {
try {
options.params = JSON.stringify(options.params);
} catch (err) {
throw new Error(err.message);
}
} else {
options.params = null;
}
options.contentType = 'application/json; charset=UTF-8';
} else {
if (options.params) {
try {
options.params = asynjax.param(options.params);
} catch (err) {
throw new Error(err.message);
}
} else {
options.params = null;
}
options.contentType = options.contentType || 'application/x-www-form-urlencoded; charset=UTF-8';
}
}
asynjax.send(url, 'POST', xFunction, options);
} else {
console.error("Asynjax error: Parámetro inválido, se requiere un objeto.");
return false;
}
} else {
console.error("Asynjax error: No se encontró la función de salida.");
return false;
}
};
//----//