126 lines
3.4 KiB
JavaScript
126 lines
3.4 KiB
JavaScript
// Cliente API moderno con fetch nativo (Vanilla JS)
|
|
(function(global){
|
|
'use strict';
|
|
|
|
// Helper para construir query string desde objeto
|
|
function buildQueryString(params) {
|
|
if (!params || Object.keys(params).length === 0) return '';
|
|
const query = Object.keys(params)
|
|
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
|
.join('&');
|
|
return '?' + query;
|
|
}
|
|
|
|
// Helper para manejar respuestas fetch
|
|
async function handleResponse(response) {
|
|
// Redirección automática al login en 401
|
|
if (response.status === 401) {
|
|
if (location.pathname.indexOf('login.php') === -1) {
|
|
window.location.href = '/login.php';
|
|
}
|
|
throw new Error('No autorizado');
|
|
}
|
|
|
|
// Parsear JSON o texto según content-type
|
|
const contentType = response.headers.get('content-type');
|
|
let data;
|
|
if (contentType && contentType.includes('application/json')) {
|
|
try {
|
|
data = await response.json();
|
|
} catch (err) {
|
|
const error = new Error('La API devolvió JSON inválido');
|
|
error.response = response;
|
|
throw error;
|
|
}
|
|
} else {
|
|
const text = await response.text();
|
|
data = text;
|
|
if (!response.ok || /^\s*</.test(text)) {
|
|
const error = new Error('La API devolvió HTML en lugar de JSON');
|
|
error.response = response;
|
|
error.data = text;
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
if (!response.ok) {
|
|
const error = new Error(data.message || 'Error en la petición');
|
|
error.response = response;
|
|
error.data = data;
|
|
throw error;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
// API pública
|
|
const api = {
|
|
// GET request
|
|
get: function(url, params) {
|
|
const queryString = buildQueryString(params);
|
|
return fetch(url + queryString, {
|
|
method: 'GET',
|
|
credentials: 'same-origin',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
}
|
|
}).then(handleResponse);
|
|
},
|
|
|
|
// GET JSON (alias de get para compatibilidad)
|
|
getJSON: function(url, params) {
|
|
return this.get(url, params);
|
|
},
|
|
|
|
// POST JSON
|
|
postJSON: function(url, body, options) {
|
|
const opts = options || {};
|
|
const headers = Object.assign({
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
}, opts.headers || {});
|
|
|
|
return fetch(url, {
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
headers: headers,
|
|
body: JSON.stringify(body || {})
|
|
}).then(handleResponse);
|
|
},
|
|
|
|
// PUT JSON
|
|
putJSON: function(url, body, options) {
|
|
const opts = options || {};
|
|
const headers = Object.assign({
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
}, opts.headers || {});
|
|
|
|
return fetch(url, {
|
|
method: 'PUT',
|
|
credentials: 'same-origin',
|
|
headers: headers,
|
|
body: JSON.stringify(body || {})
|
|
}).then(handleResponse);
|
|
},
|
|
|
|
// DELETE request
|
|
delete: function(url, params) {
|
|
const queryString = buildQueryString(params);
|
|
return fetch(url + queryString, {
|
|
method: 'DELETE',
|
|
credentials: 'same-origin',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
}
|
|
}).then(handleResponse);
|
|
}
|
|
};
|
|
|
|
// Exportar globalmente
|
|
global.api = api;
|
|
|
|
// Log de inicialización
|
|
try { console.log('[API Client] Inicializado (Vanilla JS)'); } catch {}
|
|
})(window);
|