[RN] Use fetch instead of XHR
This commit is contained in:
parent
7d81ec4d86
commit
f027a8f74f
|
@ -1,49 +1,55 @@
|
||||||
/**
|
/**
|
||||||
* Loads a script from a specific source. React Native cannot load a JS
|
* Loads a script from a specific URL. React Native cannot load a JS
|
||||||
* file/resource/URL via a <script> HTML element, so the implementation
|
* file/resource/URL via a <script> HTML element, so the implementation
|
||||||
* fetches the specified src as plain text (e.g. via XMLHttpRequest) and then
|
* fetches the specified src as plain text (e.g. via XMLHttpRequest) and then
|
||||||
* evaluates the fetched string as JavaScript code (i.e. via the {@link eval}
|
* evaluates the fetched string as JavaScript code (i.e. via the {@link eval}
|
||||||
* function).
|
* function).
|
||||||
*
|
*
|
||||||
* @param {string} src - The source from the which the script is to be
|
* @param {string} url - The absolute URL from the which the script is to be
|
||||||
* (down)loaded. Only absolute URLs are supported.
|
* (down)loaded.
|
||||||
* @param {Object} options - Additional options.
|
|
||||||
* @param {boolean} options.async=true - True to asynchronously load the script
|
|
||||||
* or false to synchronously load the script.
|
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
export function loadScript(
|
export function loadScript(url) {
|
||||||
src,
|
let fetch;
|
||||||
options = {
|
const method = 'GET';
|
||||||
async: true
|
|
||||||
}) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// XXX We are using XMLHttpRequest instead of Fetch API only in order
|
|
||||||
// to be able to do 'sync' requests. If this not needed, this can be
|
|
||||||
// replaced with much simpler and readable fetch().
|
|
||||||
const xhr = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhr.open('GET', src, options.async);
|
// Prefer the Fetch API. Apart from the fact that we're fetching the
|
||||||
xhr.responseType = 'text';
|
// specified script as a static resource, the Fetch API provides more
|
||||||
|
// detailed errors.
|
||||||
|
if (typeof (fetch = window.fetch) === 'function') {
|
||||||
|
fetch = fetch(url, { method });
|
||||||
|
} else {
|
||||||
|
// Otherwise, fall back to the XMLHttpRequest API.
|
||||||
|
fetch
|
||||||
|
= new Promise(resolve => {
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
xhr.onload = () => {
|
xhr.responseType = 'text';
|
||||||
if (xhr.readyState === 4) {
|
|
||||||
if (xhr.status === 200) {
|
xhr.onreadystatechange = () => {
|
||||||
try {
|
if (xhr.readyState === 4) {
|
||||||
// eslint-disable-next-line no-eval
|
resolve(xhr);
|
||||||
eval.call(window, xhr.responseText);
|
|
||||||
resolve();
|
|
||||||
} catch (e) {
|
|
||||||
reject(e);
|
|
||||||
}
|
}
|
||||||
} else {
|
};
|
||||||
reject(xhr.statusText);
|
|
||||||
|
xhr.open(method, url, /* async */ true);
|
||||||
|
xhr.send();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
fetch
|
||||||
|
.then(response => {
|
||||||
|
switch (response.status) {
|
||||||
|
case 200:
|
||||||
|
return response.responseText || response.text();
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw response.statusText;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.onerror = () => reject(xhr.statusText);
|
})
|
||||||
|
.then(responseText => {
|
||||||
xhr.send();
|
eval.call(window, responseText); // eslint-disable-line no-eval
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue