Files
daydream/src/scripts/api.js
T
2026-09-03 18:28:33 +02:00

87 lines
2.4 KiB
JavaScript

export default class Api {
constructor({server, processPage, timezone, csrfToken, errorCode, lang}) {
this.server = server;
this.processPage = processPage;
this.timezone = timezone;
this.csrfToken = csrfToken;
this.errorCode = errorCode;
this.lang = lang;
}
async get(sAction, asParams = {}) {
const oResponse = await this.request(sAction, asParams, 'GET');
return oResponse.data;
}
async post(sAction, asParams = {}) {
const oResponse = await this.request(sAction, asParams, 'POST');
return oResponse.data;
}
/**
* Fire-and-forget POST that survives the page going away. Used for the
* close-the-entry call on unload, where a fetch would simply be cancelled.
* sendBeacon cannot set headers, so the CSRF token rides in the body -
* which the controller accepts as a fallback for exactly this case.
*/
beacon(sAction, asParams = {}) {
if(!navigator.sendBeacon) return false;
const oBody = new URLSearchParams({
...asParams,
a: sAction,
t: this.timezone,
csrf_token: this.csrfToken
});
return navigator.sendBeacon(
new URL(this.processPage, this.server),
new Blob([oBody.toString()], {type: 'application/x-www-form-urlencoded;charset=UTF-8'})
);
}
async request(sAction, asParams = {}, sMethod = 'GET') {
const oUrl = new URL(this.processPage, this.server);
const sUrlParams = new URLSearchParams({
...asParams,
a: sAction,
t: this.timezone
}).toString();
const asOptions = {
method: sMethod,
headers: {'Accept': 'application/json'}
};
if(sMethod === 'GET') {
oUrl.search = sUrlParams;
}
else {
asOptions.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
asOptions.headers['X-CSRF-Token'] = this.csrfToken;
asOptions.body = sUrlParams;
}
const oRequest = await fetch(oUrl, asOptions);
if(!oRequest.ok) {
throw new Error('Error HTTP ' + oRequest.status + ': ' + oRequest.statusText);
}
const oResponse = await oRequest.json();
oResponse.desc_lang_text = this.lang.get(oResponse.desc_lang_id, oResponse.desc_lang_params);
if(oResponse.result == this.errorCode) {
const oError = new Error(oResponse.desc_lang_text || oResponse.desc_lang_id);
oError.desc_lang_id = oResponse.desc_lang_id;
oError.desc_lang_params = oResponse.desc_lang_params;
oError.desc_lang_text = oResponse.desc_lang_text;
throw oError;
}
return oResponse;
}
}