2020-05-06 00:03:42 +02:00
|
|
|
/* eslint-disable indent */
|
|
|
|
export function getFetchPromise(request) {
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
const headers = request.headers || {};
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
if (request.dataType === 'json') {
|
|
|
|
headers.accept = 'application/json';
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
const fetchRequest = {
|
2019-01-10 15:39:37 +03:00
|
|
|
headers: headers,
|
|
|
|
method: request.type,
|
|
|
|
credentials: 'same-origin'
|
|
|
|
};
|
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
let contentType = request.contentType;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
if (request.data) {
|
|
|
|
|
|
|
|
if (typeof request.data === 'string') {
|
|
|
|
fetchRequest.body = request.data;
|
|
|
|
} else {
|
|
|
|
fetchRequest.body = paramsToString(request.data);
|
|
|
|
|
|
|
|
contentType = contentType || 'application/x-www-form-urlencoded; charset=UTF-8';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (contentType) {
|
|
|
|
|
|
|
|
headers['Content-Type'] = contentType;
|
|
|
|
}
|
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
let url = request.url;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2018-10-23 01:05:09 +03:00
|
|
|
if (request.query) {
|
2020-05-06 00:03:42 +02:00
|
|
|
const paramString = paramsToString(request.query);
|
2019-01-10 15:39:37 +03:00
|
|
|
if (paramString) {
|
2020-05-06 00:03:42 +02:00
|
|
|
url += `?${paramString}`;
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!request.timeout) {
|
|
|
|
return fetch(url, fetchRequest);
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
return fetchWithTimeout(url, fetchRequest, request.timeout);
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function fetchWithTimeout(url, options, timeoutMs) {
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
console.debug(`fetchWithTimeout: timeoutMs: ${timeoutMs}, url: ${url}`);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
return new Promise(function (resolve, reject) {
|
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
const timeout = setTimeout(reject, timeoutMs);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
options = options || {};
|
|
|
|
options.credentials = 'same-origin';
|
|
|
|
|
|
|
|
fetch(url, options).then(function (response) {
|
|
|
|
clearTimeout(timeout);
|
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
console.debug(`fetchWithTimeout: succeeded connecting to url: ${url}`);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
resolve(response);
|
|
|
|
}, function (error) {
|
|
|
|
|
|
|
|
clearTimeout(timeout);
|
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
console.debug(`fetchWithTimeout: timed out connecting to url: ${url}`);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
reject(error);
|
2019-01-10 15:39:37 +03:00
|
|
|
});
|
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-05-28 23:06:36 +02:00
|
|
|
/**
|
|
|
|
* @param params {Record<string, string | number | boolean>}
|
|
|
|
* @returns {string} Query string
|
|
|
|
*/
|
2018-10-23 01:05:09 +03:00
|
|
|
function paramsToString(params) {
|
2020-05-28 23:06:36 +02:00
|
|
|
return Object.entries(params)
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
|
|
.filter(([_, v]) => v !== null && v !== undefined)
|
|
|
|
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
2020-05-06 00:03:42 +02:00
|
|
|
.join('&');
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
export function ajax(request) {
|
2019-01-10 15:39:37 +03:00
|
|
|
if (!request) {
|
2020-05-04 12:44:12 +02:00
|
|
|
throw new Error('Request cannot be null');
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
request.headers = request.headers || {};
|
|
|
|
|
2020-05-06 00:03:42 +02:00
|
|
|
console.debug(`requesting url: ${request.url}`);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
return getFetchPromise(request).then(function (response) {
|
2020-05-06 00:03:42 +02:00
|
|
|
console.debug(`response status: ${response.status}, url: ${request.url}`);
|
2019-01-10 15:39:37 +03:00
|
|
|
if (response.status < 400) {
|
|
|
|
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
|
|
|
|
return response.json();
|
2020-05-26 23:59:58 +02:00
|
|
|
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().startsWith('text/')) {
|
2019-01-10 15:39:37 +03:00
|
|
|
return response.text();
|
|
|
|
} else {
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return Promise.reject(response);
|
|
|
|
}
|
|
|
|
}, function (err) {
|
2020-05-06 00:03:42 +02:00
|
|
|
console.error(`request failed to url: ${request.url}`);
|
2019-01-10 15:39:37 +03:00
|
|
|
throw err;
|
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2020-05-06 00:03:42 +02:00
|
|
|
/* eslint-enable indent */
|