From f027a8f74fcdf06e50622775aaf7a55374d65a3c Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Wed, 7 Dec 2016 16:00:54 -0600 Subject: [PATCH] [RN] Use fetch instead of XHR --- react/features/base/util/loadScript.native.js | 76 ++++++++++--------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/react/features/base/util/loadScript.native.js b/react/features/base/util/loadScript.native.js index 8f80821d3..ce5926d11 100644 --- a/react/features/base/util/loadScript.native.js +++ b/react/features/base/util/loadScript.native.js @@ -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 * 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} * function). * - * @param {string} src - The source from the which the script is to be - * (down)loaded. Only absolute URLs are supported. - * @param {Object} options - Additional options. - * @param {boolean} options.async=true - True to asynchronously load the script - * or false to synchronously load the script. + * @param {string} url - The absolute URL from the which the script is to be + * (down)loaded. * @returns {void} */ -export function loadScript( - src, - options = { - 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(); +export function loadScript(url) { + let fetch; + const method = 'GET'; - xhr.open('GET', src, options.async); - xhr.responseType = 'text'; + // Prefer the Fetch API. Apart from the fact that we're fetching the + // 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 = () => { - if (xhr.readyState === 4) { - if (xhr.status === 200) { - try { - // eslint-disable-next-line no-eval - eval.call(window, xhr.responseText); - resolve(); - } catch (e) { - reject(e); + xhr.responseType = 'text'; + + xhr.onreadystatechange = () => { + if (xhr.readyState === 4) { + resolve(xhr); } - } 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); - - xhr.send(); - }); + }) + .then(responseText => { + eval.call(window, responseText); // eslint-disable-line no-eval + })); }