XHR request support for legacy browsers

This commit is contained in:
Bruno Windels 2020-08-05 15:37:37 +00:00
parent b26bc69042
commit 69142909d9

View file

@ -0,0 +1,81 @@
import {
AbortError,
ConnectionError
} from "../../error.js";
class RequestResult {
constructor(promise, xhr) {
this._promise = promise;
this._xhr = xhr;
}
abort() {
this._xhr.abort();
}
response() {
return this._promise;
}
}
function send(url, options) {
const xhr = new XMLHttpRequest();
xhr.open(options.method, url);
if (options.headers) {
for(const [name, value] of options.headers.entries()) {
xhr.setRequestHeader(name, value);
}
}
if (options.timeout) {
xhr.timeout = options.timeout;
}
xhr.send(options.body || null);
return xhr;
}
function xhrAsPromise(xhr, method, url) {
return new Promise((resolve, reject) => {
xhr.addEventListener("load", () => resolve(xhr));
xhr.addEventListener("abort", () => reject(new AbortError()));
xhr.addEventListener("error", () => reject(new ConnectionError(`Error ${method} ${url}`)));
xhr.addEventListener("timeout", () => reject(new ConnectionError(`Timeout ${method} ${url}`, true)));
});
}
function addCacheBuster(urlStr, random = Math.random) {
// XHR doesn't have a good way to disable cache,
// so add a random query param
// see https://davidtranscend.com/blog/prevent-ie11-cache-ajax-requests/
if (urlStr.includes("?")) {
urlStr = urlStr + "&";
} else {
urlStr = urlStr + "?";
}
return urlStr + `_cacheBuster=${Math.ceil(random() * Number.MAX_SAFE_INTEGER)}`;
}
export function xhrRequest(url, options) {
url = addCacheBuster(url);
const xhr = send(url, options);
const promise = xhrAsPromise(xhr, options.method, url).then(xhr => {
const {status} = xhr;
let body = xhr.responseText;
if (xhr.getResponseHeader("Content-Type") === "application/json") {
body = JSON.parse(body);
}
return {status, body};
});
return new RequestResult(promise, xhr);
}
export function tests() {
return {
"add cache buster": assert => {
const random = () => 0.5;
assert.equals(addCacheBuster("http://foo", random), "http://foo?_cacheBuster=5");
assert.equals(addCacheBuster("http://foo?bar=baz", random), "http://foo?bar=baz&_cacheBuster=5");
}
}
}