accept xhr options in download(url, options)

also fixup d1964bbc: an error should reject with a code, not XHR's ProgressEvent
This commit is contained in:
tophf 2017-11-24 22:30:39 +03:00
parent ff175d9af4
commit 0d80177691

View File

@ -408,49 +408,47 @@ function deleteStyleSafe({id, notify = true} = {}) {
} }
function download(url) { function download(url, {
method = url.includes('?') ? 'POST' : 'GET',
body = url.includes('?') ? url.slice(url.indexOf('?')) : null,
requiredStatusCode = 200,
timeout = 10e3,
headers = {
'Content-type': 'application/x-www-form-urlencoded',
},
} = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
url = new URL(url); url = new URL(url);
const TIMEOUT = 10000;
const options = {
method: url.search ? 'POST' : 'GET',
body: url.search ? url.search.slice(1) : null,
headers: {
'Content-type': 'application/x-www-form-urlencoded'
}
};
if (url.protocol === 'file:' && FIREFOX) { if (url.protocol === 'file:' && FIREFOX) {
// https://stackoverflow.com/questions/42108782/firefox-webextensions-get-local-files-content-by-path // https://stackoverflow.com/questions/42108782/firefox-webextensions-get-local-files-content-by-path
options.mode = 'same-origin';
// FIXME: add FetchController when it is available. // FIXME: add FetchController when it is available.
// https://developer.mozilla.org/en-US/docs/Web/API/FetchController/abort const timer = setTimeout(reject, timeout, new Error('Timeout fetching ' + url.href));
let timer;
fetch(url.href, {mode: 'same-origin'}) fetch(url.href, {mode: 'same-origin'})
.then(r => { .then(r => {
clearTimeout(timer); clearTimeout(timer);
if (r.status !== 200) { return r.status === 200 ? r.text() : Promise.reject(r.status);
throw r.status;
}
return r.text();
}) })
.then(resolve, reject); .catch(reject)
timer = setTimeout( .then(resolve);
() => reject(new Error(`Fetch URL timeout: ${url.href}`)),
TIMEOUT
);
return; return;
} }
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.timeout = TIMEOUT; xhr.timeout = timeout;
xhr.onload = () => (xhr.status === 200 || url.protocol === 'file:' xhr.onloadend = event => {
? resolve(xhr.responseText) if (event.type !== 'error' && (
: reject(xhr.status)); xhr.status === requiredStatusCode || !requiredStatusCode ||
xhr.onerror = reject; url.protocol === 'file:')) {
xhr.open(options.method, url.href, true); resolve(xhr.responseText);
for (const key of Object.keys(options.headers)) { } else {
xhr.setRequestHeader(key, options.headers[key]); reject(xhr.status);
}
};
xhr.onerror = xhr.onloadend;
xhr.open(method, url.href, true);
for (const key in headers) {
xhr.setRequestHeader(key, headers[key]);
} }
xhr.send(options.body); xhr.send(body);
}); });
} }