Tengo un documento html que contiene el siguiente código:
... <head> ... <link href="//assets.example.com/css/bootstrap.min.css" rel="stylesheet"> <script src="//assets.example.com/js/bootstrap.bundle.min.js"></script> </head> ...El contexto:
Este documento html se encuentra en el SPIFFS de un microcontrolador. El chip aloja un pequeño servidor web y puede servir archivos estáticos (como, por ejemplo, este archivo html). Se puede acceder al servidor web desde Internet (automation.example.com) o desde mi red wifi local (192.168.0.49:1337).
El problema :
La lectura de archivos estáticos de la memoria del chip es muy lenta (se tarda unos 7 segundos en obtener un HTTP 200 del servidor web cuando solicito el css autohospedado).
Es por eso que moví todos los archivos css/js a mi CDN. La respuesta ahora es ultrarrápida, pero tengo que considerar el caso cuando Internet no funciona (los activos no se cargan) y solo puedo acceder al chip a través de mi red local.
La solución :
Quiero cargar esos activos desde mi cdn si se accede al chip desde Internet (con direcciones URL absolutas) o desde SPIFFS si Internet no funciona (con direcciones URL relativas).
En otras palabras, estoy pensando en la siguiente lógica: si la URL del navegador es una IP o termina con ".local" (DNS de multidifusión), incluya así:
<link href="/bootstrap.min.css" rel="stylesheet">de lo contrario, si la URL del navegador es mi dominio "example.com", incluya así:
<link href="//assets.example.com/css/bootstrap.min.css" rel="stylesheet"> ¿Me pueden ayudar con el código js? Solo puedo usar el código del lado del cliente. Creo que voy a necesitar window.location.hostname y algunas expresiones regulares, pero ¿hay formas más elegantes de hacerlo?
Hasta ahora he intentado esto sin ningún gran éxito:
<head> ... <script> let hostname = window.location.hostname; let cdn = ''; if ('automation.example.com' === hostname) { cdn = '//assets.example.com'; } var head = document.getElementsByTagName('head')[0]; head.insertAdjacentHTML('beforeend', '<link href="' + cdn + '/css/bootstrap.min.css" rel="stylesheet">'); head.insertAdjacentHTML('beforeend', '<link href="' + cdn + '/css/login.css" rel="stylesheet">'); head.insertAdjacentHTML('beforeend', '<script src="' + cdn + '/js/bootstrap.bundle.min.js"></script>'); </script> </head> No le gusta la parte de inserción del "script": Uncaught SyntaxError: '' literal not terminated before end of script
Tal vez necesito Promesas para evitar el flasheo del DOM
<head> ... <link id="aaa" href="//assets.example.com/css/bootstrap.min.css" rel="stylesheet"> <link id="bbb" href="//assets.example.com/css/login.css" rel="stylesheet"> <script id="ccc" src="//assets.example.com/js/bootstrap.bundle.min.js"></script> <script> let hostname = window.location.hostname; let cdn = ''; // SPIFFS if ('automation.example.com' === hostname) { cdn = '//assets.example.com'; } // bootstrap.min.css let aaa = document.getElementById('aaa'); aaa.href = cdn + '/css/bootstrap.min.css'; // login.css let bbb = document.getElementById('bbb'); bbb.href = cdn + '/css/login.css'; // bootstrap.bundle.min.js let ccc = document.getElementById('ccc'); ccc.src = cdn + '/js/bootstrap.bundle.min.js'; </script> </head>Esto funciona, pero estoy buscando una solución más elegante. Intenta cargar los activos desde el cdn sin importar el contexto (internet/red local). Si tenemos internet, pedirá los archivos dos veces, lo cual no es gran cosa ya que están en caché. Si no tenemos internet, se cargará desde el sistema de archivos del chip.
Editar: vea el comentario de @ColdIV para la solución.