[RN] Use fetch instead of XHR

This commit is contained in:
Lyubomir Marinov 2016-12-07 16:00:54 -06:00
parent 7d81ec4d86
commit f027a8f74f
1 changed files with 41 additions and 35 deletions

View File

@ -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
}); }));
} }