¿Cómo incluir archivos CSS y JS a través de HTTPS cuando sea necesario?

78

Estoy agregando un archivo CSS externo y un archivo JS externo a mis encabezados y pies de página. Al cargar una página HTTPS, algunos navegadores se quejan de que estoy cargando contenido no seguro.

¿Existe una manera fácil de hacer que el navegador cargue el contenido externo a través de HTTPS cuando la página en sí es HTTPS?

Nathan H
fuente

Respuestas:

125

Utilice rutas relativas al protocolo.

Así no

<link rel="stylesheet" href="http://example.com/style.css">
<script src="http://example.com/script.js"></script>

pero entonces

<link rel="stylesheet" href="//example.com/style.css">
<script src="//example.com/script.js"></script>

luego usará el protocolo de la página principal.

BalusC
fuente
4
Ese es un problema específico del navegador. No hay otras formas de resolver esto de manera robusta que hacerlo completamente en el lado del servidor utilizando las capacidades de la tecnología de visualización en cuestión.
BalusC
1
Como nota adicional, si se preocupa por las entradas de almacenamiento en caché correctas en los encabezados de respuesta, los navegadores no lo descargarán en las solicitudes posteriores hasta que se alcance el vencimiento, incluido IE.
BalusC
Yo diría que siempre use los https://recursos cuando estén disponibles. Se cargarán bien en su página, independientemente del esquema
Phil
@Phil: no si el entorno de destino no admite HTTPS, generalmente durante el desarrollo en localhost.
BalusC
@BalusC "... cuando esté disponible ..."
Phil
7

nute y James Westgate tienen razón al comentar la respuesta posterior.

Si echamos un vistazo a varias inclusiones de javascript externas de grado industrial, las exitosas usan tanto el rastreo de document.location.protocol como la inyección de elementos de script para usar el protocolo adecuado.

Entonces podrías usar algo como:

<script type="text/javascript">
  var protocol = (
      ("https:" == document.location.protocol) 
      ? "https" 
      : "http"
  );
  document.write(
      unescape(
          "%3Cscript"
              + " src='"
                  + protocol 
                  + "://"
                  + "your.domain.tld"
                  + "/your/script.js"
              + "'"
              + " type='text/javascript'
          + "%3E"
          + "%3C/script%3E"
      ) // this HAS to be escaped, otherwise it would 
        // close the actual (not injected) <script> element
  );
</script>

Lo mismo se puede hacer para las inclusiones CSS externas.

Y, por cierto: tenga cuidado de usar solo la ruta URL () relativa en su CSS, si corresponde, de lo contrario, es posible que reciba la advertencia "mixta segura y no segura" ...

Alain BECKER
fuente
Esto es solo algo que debe tener en cuenta al decidir qué tecnología usar. Si no puede hacer esto en el lado del servidor y necesita ir a través de los hosts, entonces no tiene otra opción.
Geoff
1

Si usa rutas relativas (y el contenido está en el mismo dominio), entonces el contenido debe usar el protocolo en el que se solicitó la página.

Sin embargo, si va a través del dominio a una CDN o un sitio de recursos, o si necesita usar rutas absolutas, deberá usar el script del lado del servidor para cambiar los enlaces, o usar siempre https: //

James Westgate
fuente
Atravesamos el dominio. ¿Usaría javascript para escribir la inclusión funcionaría? Si document.location.protocol entonces ...
Nathan H
Intentando usar js insertando un marcado en la etiqueta HEAD, tal vez un simple document.write dentro de una etiqueta de script .. <HEAD> <SCRIPT> document.write ('<SCRIPT src =' + document.location.protocol ...
James Westgate
1
Este es el enfoque adoptado por el código de Google Analytics, simplemente hace un document.write con el protocolo de la página que lo contiene.
Geoff
"Necesitará utilizar un script del lado del servidor" - ¿por qué? Almacenamiento en caché ¿Preocupaciones XSS? Navegadores?
mlhDev
Esto parece que me refería a rutas de protocolo relativ cuando respondí la pregunta, pero no puedo estar seguro. Sé que IE8 y los siguientes tienen un problema de almacenamiento en caché con las rutas relativas del protocolo que deben verificarse. No escribiría cada recurso usando un script si está interesado en el rendimiento, puede desencadenar todo tipo de problemas de asincronía y bloqueo.
James Westgate
0

En contradicción con la respuesta de escape (que también funcionará), puede omitir esa parte y usar la forma correcta de agregar nodos a su árbol de dom:

<script type="text/javascript" language="javascript">
    var fileref=document.createElement('script');
    fileref.setAttribute("type","text/javascript");
    fileref.setAttribute("src", document.location.protocol + '//www.mydomain.com/script.js');
    document.getElementsByTagName("head")[0].appendChild(fileref);
</script>

Pero la ruta relativa al protocolo sería el camino a seguir.

gkempkens
fuente