export const fetchHeaders = Object.freeze({ Accept: 'text/html', 'Content-Type': 'text/html', 'X-Requested-With': 'XMLHttpRequest', 'Cache-Control': 'no-cache', Pragma: 'no-cache', Expires: '0', }); /** * Creates an abortable AJAX request. * * @param {string} url Request endpoint. * @param {RequestInit} options Fetch options. * @returns {{fetchPromise: () => Promise, abort: () => void}} Request controls. * @sideEffects Starts a network request. */ export function AjaxReq(url, options = {}) { const controller = new AbortController(); const headers = { ...fetchHeaders, ...options.headers }; if (options.body instanceof FormData) { delete headers['Content-Type']; } const requestOptions = { ...options, headers, signal: controller.signal }; const fetchPromise = fetch(url, requestOptions).then(parseJsonResponse); return { fetchPromise: () => fetchPromise, abort: () => controller.abort(), }; } /** * Returns the JSON body of a successful HTTP response. * * @param {Response} response Fetch response. * @returns {Promise} Parsed response body. * @throws {Response} When the response status is not successful. */ function parseJsonResponse(response) { if (!response.ok) { return Promise.reject(response); } return response.json(); }