Files
accounting_dev_v2/assets/js/app-network.js
T
2026-09-11 16:03:00 +07:00

115 lines
4.6 KiB
JavaScript

(function (window, document) {
'use strict';
var nativeFetch = window.fetch.bind(window);
function toast(text) {
var old = document.querySelector('.ajax-error-toast');
if (old) old.remove();
var element = document.createElement('div');
element.className = 'ajax-error-toast';
element.setAttribute('role', 'alert');
element.textContent = text;
document.body.appendChild(element);
window.setTimeout(function () { element.remove(); }, 7000);
}
function addCsrf(formData) {
var token = window.APP_CSRF;
if (token && token.name && !formData.has(token.name)) {
formData.append(token.name, token.value);
}
return formData;
}
function secureFetch(url, options) {
options = Object.assign({}, options || {});
var method = String(options.method || 'GET').toUpperCase();
var token = window.APP_CSRF;
var target;
try {
target = new URL(url, window.location.href);
} catch (_error) {
target = null;
}
if (target && target.origin === window.location.origin && !/^(GET|HEAD|OPTIONS)$/.test(method) && token && token.name) {
if (options.body instanceof FormData) {
addCsrf(options.body);
} else if (options.body instanceof URLSearchParams) {
options.body = new URLSearchParams(options.body);
if (!options.body.has(token.name)) options.body.append(token.name, token.value);
}
}
return nativeFetch(url, options);
}
window.fetch = secureFetch;
async function request(url, options) {
options = options || {};
options.headers = Object.assign({
Accept: 'application/json',
'X-Requested-With': 'XMLHttpRequest'
}, options.headers || {});
if (options.body instanceof FormData) addCsrf(options.body);
var response;
try {
response = await window.fetch(url, options);
} catch (error) {
throw new Error('Tidak dapat terhubung ke server. Periksa jaringan atau Apache.');
}
var contentType = response.headers.get('content-type') || '';
if (contentType.indexOf('application/json') === -1) {
var raw = await response.text();
if (response.redirected || /<(?:html|!doctype)/i.test(raw)) {
throw new Error('Sesi berakhir atau server mengirim halaman error. Silakan login ulang.');
}
throw new Error(raw.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 240) || 'Respons server tidak valid.');
}
var payload = await response.json();
if (!response.ok) throw new Error(payload.message || ('Permintaan gagal (HTTP ' + response.status + ').'));
return payload;
}
window.App = Object.assign(window.App || {}, {
request: request,
addCsrf: addCsrf,
showError: toast
});
if (window.jQuery) {
window.jQuery.ajaxSetup({headers: {'X-Requested-With': 'XMLHttpRequest'}});
window.jQuery.ajaxPrefilter(function (options, originalOptions) {
var method = String(options.type || options.method || 'GET').toUpperCase();
var token = window.APP_CSRF;
if (/^(GET|HEAD|OPTIONS)$/.test(method) || !token || !token.name) return;
if (options.data instanceof FormData) {
if (!options.data.has(token.name)) options.data.append(token.name, token.value);
return;
}
if (typeof options.data === 'string') {
var encodedName = encodeURIComponent(token.name);
if (options.data.indexOf(encodedName + '=') === -1) {
options.data += (options.data ? '&' : '') + encodedName + '=' + encodeURIComponent(token.value);
}
return;
}
options.data = window.jQuery.extend({}, originalOptions.data || options.data || {});
if (typeof options.data[token.name] === 'undefined') options.data[token.name] = token.value;
});
window.jQuery(document).ajaxError(function (_event, xhr, _settings, error) {
var message = 'Pemanggilan data gagal';
if (xhr.status === 401 || xhr.status === 403) message = 'Sesi atau hak akses tidak valid. Silakan login ulang.';
else if (xhr.status) message += ' (HTTP ' + xhr.status + ').';
else message += '. Periksa koneksi atau Apache.';
toast(error && error !== 'error' ? error : message);
});
}
}(window, document));