87 lines
2.4 KiB
JavaScript
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;
|
|
}
|
|
}
|