Tratar con contenido HTTP en páginas HTTPS


Tenemos un sitio al que se accede completamente a través de HTTPS, pero a veces se muestra contenido externo que es HTTP (imágenes de fuentes RSS, principalmente). La gran mayoría de nuestros usuarios también están atascados en IE6.

Idealmente me gustaría hacer las dos siguientes

  • Evitar el mensaje de advertencia de IE sobre contenido inseguro (para que pueda mostrar uno menos intrusivo, por ejemplo, reemplazando las imágenes con un icono predeterminado como se muestra a continuación)
  • Presente algo útil para los usuarios en su lugar de las imágenes que de otra manera no pueden ver; si hubiera algunos JS que podría ejecutar para averiguar qué imágenes no se han cargado y reemplazarlos con una imagen de la nuestra en lugar de eso sería genial.

Sospecho que el primer objetivo simplemente no es posible, pero el segundo puede ser suficiente.

En el peor de los casos, analizo las fuentes RSS cuando las importamos, agarro las imágenes y las almaceno localmente para que los usuarios puedan acceder a ellas de esa manera, pero parece un montón de dolor para razonablemente poca ganancia.

Author: El Yobo, 2010-06-10

10 answers

Tu peor escenario no es tan malo como crees.

Ya está analizando la fuente RSS, por lo que ya tiene las URL de las imágenes. Digamos que tienes una URL de imagen como http://otherdomain.com/someimage.jpg. Reescribe esta URL como https://mydomain.com/imageserver?url=http://otherdomain.com/someimage.jpg&hash=abcdeafad. De esta manera, el navegador siempre realiza la solicitud a través de https, por lo que se deshace de los problemas.

La siguiente parte - crear una página proxy o servlet que haga lo siguiente -

  1. Lea el parámetro url de la cadena de consulta y verifique el hash
  2. Descargar el imagen del servidor, y proxy de nuevo al navegador
  3. Opcionalmente, almacenar en caché la imagen en el disco

Esta solución tiene algunas ventajas. No tienes que descargar la imagen en el momento de crear el html. No tienes que almacenar las imágenes localmente. Además, eres apátrida; la url contiene toda la información necesaria para servir la imagen.

Finalmente, el parámetro hash es por seguridad; solo desea que su servlet sirva imágenes para las URL que ha construido. Tan, cuando cree la url, calcule md5(image_url + secret_key) y añádala como parámetro hash. Antes de entregar la solicitud, vuelva a calcular el hash y compárelo con lo que se le pasó. Dado que el secret_key solo es conocido por usted, nadie más puede construir urls válidas.

Si está desarrollando en java, el Servlet es solo unas pocas líneas de código. Usted debe ser capaz de portar el código a continuación en cualquier otra tecnología de back-end.

/*
targetURL is the url you get from RSS feeds
request and response are wrt to the browser
Assumes you have commons-io in your classpath
*/

protected void proxyResponse (String targetURL, HttpServletRequest request,
 HttpServletResponse response) throws IOException {
    GetMethod get = new GetMethod(targetURL);
    get.setFollowRedirects(true);    
    /*
     * Proxy the request headers from the browser to the target server
     */
    Enumeration headers = request.getHeaderNames();
    while(headers!=null && headers.hasMoreElements())
    {
        String headerName = (String)headers.nextElement();

        String headerValue = request.getHeader(headerName);

        if(headerValue != null)
        {
            get.addRequestHeader(headerName, headerValue);
        }            
    }        

    /*Make a request to the target server*/
    m_httpClient.executeMethod(get);
    /*
     * Set the status code
     */
    response.setStatus(get.getStatusCode());

    /*
     * proxy the response headers to the browser
     */
    Header responseHeaders[] = get.getResponseHeaders();
    for(int i=0; i<responseHeaders.length; i++)
    {
        String headerName = responseHeaders[i].getName();
        String headerValue = responseHeaders[i].getValue();

        if(headerValue != null)
        {
            response.addHeader(headerName, headerValue);
        }
    }

    /*
     * Proxy the response body to the browser
     */
    InputStream in = get.getResponseBodyAsStream();
    OutputStream out = response.getOutputStream();

    /*
     * If the server sends a 204 not-modified response, the InputStream will be null.
     */
    if (in !=null) {
        IOUtils.copy(in, out);
    }    
}
 141
Author: Sripathi Krishnan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-15 05:38:09

Si está buscando una solución rápida para cargar imágenes a través de HTTPS, entonces el servicio gratuito de proxy inverso en https://images.weserv.nl / puede interesarle. Era exactamente lo que estaba buscando.

Si está buscando una solución de pago, he utilizado anteriormente Cloudinary.com que también funciona bien, pero es demasiado caro únicamente para esta tarea, en mi opinión.

 9
Author: nullable,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-04 02:49:41

No se si esto se ajustaría a lo que estás haciendo, pero como una solución rápida "envolver" el contenido http en un script https. Por ejemplo, en su página que se sirve a través de https introduciría un iframe que reemplazaría su fuente rss y en el attr src del iframe pondría una url de un script en su servidor que capture la fuente y genere el html. el script está leyendo el feed a través de http y lo envía a través de https (por lo tanto, "wrapping")

Solo un pensamiento

 3
Author: Raine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-14 07:14:40

Con respecto a su segundo requisito - es posible que pueda utilizar el evento onerror, es decir. <img onerror="some javascript;"...

Actualización:

También puedes intentar iterar a través de document.images en el dom. Hay una propiedad booleana complete que podría ser capaz de usar. No estoy seguro de si esto será adecuado, pero podría valer la pena investigarlo.

 2
Author: UpTheCreek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-14 10:09:11

Sería mejor tener solo el contenido http en https

 0
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-14 11:58:30

A veces como en las aplicaciones de Facebook no podemos tener contenidos no seguros en la página segura. tampoco podemos hacer locales esos contenidos. por ejemplo, una aplicación que se cargará en iFrame no es un contenido simple y no podemos hacerlo local.

Creo que nunca debemos cargar el contenido http en https, tampoco debemos recurrir a la página https en la versión http para evitar el diálogo de error.

La única forma de garantizar la seguridad del usuario es usar la versión https de todos los contenidos, http://developers.facebook.com/blog/post/499 /

 0
Author: Mohammad Ali Akbari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-03 17:18:28

La respuesta aceptada me ayudó a actualizar esto tanto a PHP como a CORS, así que pensé en incluir la solución para otros:

PHP/HTML puro:

<?php // (the originating page, where you want to show the image)
// set your image location in whatever manner you need
$imageLocation = "http://example.com/exampleImage.png";

// set the location of your 'imageserve' program
$imageserveLocation = "https://example.com/imageserve.php";

// we'll look at the imageLocation and if it is already https, don't do anything, but if it is http, then run it through imageserve.php
$imageURL = (strstr("https://",$imageLocation)?"": $imageserveLocation . "?image=") . $imageLocation;

?>
<!-- this is the HTML image -->
<img src="<?php echo $imageURL ?>" />

Javascript / jQuery:

<img id="theImage" src="" />
<script>
    var imageLocation = "http://example.com/exampleImage.png";
    var imageserveLocation = "https://example.com/imageserve.php";
    var imageURL = ((imageLocation.indexOf("https://") !== -1) ? "" : imageserveLocation + "?image=") + imageLocation;
    // I'm using jQuery, but you can use just javascript...        
    $("#theImage").prop('src',imageURL);
</script>

Imageserve.php véase http://stackoverflow.com/questions/8719276/cors-with-php-headers?noredirect=1&lq=1 para más información sobre CORS

<?php
// set your secure site URL here (where you are showing the images)
$mySecureSite = "https://example.com";

// here, you can set what kinds of images you will accept
$supported_images = array('png','jpeg','jpg','gif','ico');

// this is an ultra-minimal CORS - sending trusted data to yourself 
header("Access-Control-Allow-Origin: $mySecureSite");

$parts = pathinfo($_GET['image']);
$extension = $parts['extension'];
if(in_array($extension,$supported_images)) {
    header("Content-Type: image/$extension");
    $image = file_get_contents($_GET['image']);
    echo $image;
}
 0
Author: CFP Support,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-02 10:33:53

Simplemente: NO LO HAGAS. El contenido Http dentro de una página HTTPS es inherentemente inseguro. Punto. Es por eso que IE muestra una advertencia. Deshacerse de la advertencia es un enfoque estúpido.

En su lugar, una página HTTPS debería solo tener contenido HTTPS. Asegúrese de que el contenido también se pueda cargar a través de HTTPS y haga referencia a él a través de https si la página se carga a través de https. Para el contenido externo, esto significará cargar y almacenar en caché los elementos localmente para que estén disponibles a través de https - sure. De ninguna manera por eso, tristemente.

La advertencia está ahí por una buena razón. Seriamente. Pase 5 minutos pensando cómo podría hacerse cargo de una página https mostrada con contenido personalizado - se sorprenderá.

 -2
Author: TomTom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-14 06:35:27

La Mejor manera de trabajar para mí

<img src="/path/image.png" />// this work only online
    or
    <img src="../../path/image.png" /> // this work both
    or asign variable
    <?php 
    $base_url = '';
    if($_SERVER['HTTP_HOST'] == 'localhost')
    {
         $base_url = 'localpath'; 
    }
    ?>
    <img src="<?php echo $base_url;?>/path/image.png" /> 
 -2
Author: sandeep kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 12:07:57

Me doy cuenta de que este es un hilo antiguo, pero una opción es eliminar la parte http: de la URL de la imagen para que ' http://some/image.jpg ' becomes '//some/image.jpg". Esto también funcionará con CDNs

 -3
Author: Shmarkus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-12 20:12:52