Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

loadScript.native.ts 2.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /**
  2. * Default timeout for loading scripts.
  3. */
  4. const DEFAULT_TIMEOUT = 5000;
  5. /**
  6. * Loads a script from a specific URL. React Native cannot load a JS
  7. * file/resource/URL via a <script> HTML element, so the implementation
  8. * fetches the specified {@code url} as plain text using {@link fetch()} and
  9. * then evaluates the fetched string as JavaScript code (using {@link eval()}).
  10. *
  11. * @param {string} url - The absolute URL from which the script is to be
  12. * (down)loaded.
  13. * @param {number} [timeout] - The timeout in millisecnods after which the
  14. * loading of the specified {@code url} is to be aborted/rejected (if not
  15. * settled yet).
  16. * @param {boolean} skipEval - Whether we want to skip evaluating the loaded content or not.
  17. * @returns {void}
  18. */
  19. export async function loadScript(
  20. url: string, timeout: number = DEFAULT_TIMEOUT, skipEval = false): Promise<any> {
  21. // XXX The implementation of fetch on Android will throw an Exception on
  22. // the Java side which will break the app if the URL is invalid (which
  23. // the implementation of fetch on Android calls 'unexpected url'). In
  24. // order to try to prevent the breakage of the app, try to fail on an
  25. // invalid URL as soon as possible.
  26. const { hostname, pathname, protocol } = new URL(url);
  27. // XXX The standard URL implementation should throw an Error if the
  28. // specified URL is relative. Unfortunately, the polyfill used on
  29. // react-native does not.
  30. if (!hostname || !pathname || !protocol) {
  31. throw new Error(`unexpected url: ${url}`);
  32. }
  33. const controller = new AbortController();
  34. const signal = controller.signal;
  35. const timer = setTimeout(() => {
  36. controller.abort();
  37. }, timeout);
  38. const response = await fetch(url, { signal });
  39. // If the timeout hits the above will raise AbortError.
  40. clearTimeout(timer);
  41. switch (response.status) {
  42. case 200: {
  43. const txt = await response.text();
  44. if (skipEval) {
  45. return txt;
  46. }
  47. return eval.call(window, txt); // eslint-disable-line no-eval
  48. }
  49. default:
  50. throw new Error(`loadScript error: ${response.statusText}`);
  51. }
  52. }