async function ajax(method, url, body, noJSON, skipDataSerialize, tokenOverride, formData) { let data = body //check if has File object in body let hasFiles = false for (let key in data) { if (data[key]?.value instanceof File) hasFiles = true } if (!skipDataSerialize) { data = body ? JSON.stringify(body) : null } //let tokenExpired = false let ctype = noJSON ? (skipDataSerialize ? 'text/plain' : null) : "application/json; charset=utf-8" let params = { type: method, url: url, headers: { "Authorization": 'Bearer ' + (tokenOverride || getToken()), }, data, contentType: ctype, dataType: noJSON ? null : 'json', } if (formData || hasFiles) { let fd = new FormData() let files = {} for (let key in body) { if (body[key]?.value instanceof File) { files[key] = body[key].value //delete body[key] } } fd.append('data', JSON.stringify(body)) for (let key in files) { fd.append(key, files[key]) } params.data = fd params.processData = false params.contentType = false params.cache = false params.enctype = 'multipart/form-data' params.xhr = function () { var xhr = new window.XMLHttpRequest() xhr.upload.addEventListener("progress", function(evt) { if (evt.lengthComputable) { var percentComplete = (evt.loaded / evt.total) * 100 loaderSetPercentage(percentComplete) } }, false) return xhr } loaderShow("Uploading files...", true, true) } try { return await $.ajax(params) } catch (ex) { console.log("ajax error", ex) if (ex.status == 401 && ex.responseJSON?.error == "E_TENANT_MISSMATCH") { logout() } else if (ex.status == 401 && ex.responseJSON?.error == "E_TOKEN_EXPIRED") { //retry one time let success = await refreshToken(getRefreshToken()) if (!success) { location.href = '' return } params.headers.Authorization = getToken() return await $.ajax(params) } else { throw ex } } finally { loaderHide(); } } async function post(url, body, tokenOverride, noJSON, skipDataSerialize) { return ajax("POST", url, body, noJSON, skipDataSerialize, tokenOverride) } async function tkpost(url, body, noJSON, skipDataSerialize) { return ajax("POST", url, body, noJSON, skipDataSerialize) } /*async function tkpostfile(url, file) { return ajax("POST", url, file, true, true, null, true); }*/ async function tkput(url, body, noJSON, skipDataSerialize) { return ajax("PUT", url, body, noJSON, skipDataSerialize) } async function tkget(url, query, noJSON) { return ajax("GET", url, query, noJSON, true) } async function tkhead(url, query, noJSON) { return ajax("HEAD", url, query, noJSON, true) } async function tkdelete(url, query, noJSON) { return ajax("DELETE", url, query || {}, noJSON, false) } $.ajaxSetup({ error: async function (xhr, status, err) { if (xhr.status == 401) { if (xhr.responseJSON.error == "token-expired") { /* if(tokenExpiredCounter[this.url] > 2){ clearForLogout(); } if(!tokenExpiredCounter[this.url]) { tokenExpiredCounter[this.url] = 1; }else{ tokenExpiredCounter[this.url]++; } let success = await refreshToken(getRefreshToken()); if (!success){ clearForLogout(); } this.headers.Authorization = getToken(); $.ajax(this); */ return; } clearForLogout() } } })