Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/04/2011, à 21:12

luigifab

[Résolu / JavaScript] Préchargement d'image avec l'objet Image

Bonsoir

J'ai un gros problème en JavaScript avec l'objet Image sous WebKit (Chromium/Chrome/Safari).
Je n'ai pas ce problème sous Gecko (Firefox) et Presto (Opera).

Voici la partie de mon script qui pose problème (est ici admis que apijs.dialogue existe) :

function Dialogue() {
    this.image = null;
    this.loadImage = function (width, height, url) {

        //alert(url);
        this.image = new Image(width, height);
        this.image.src = url;

        // eventListener:load
        this.image.addEventListener('load', function () {

            if (document.getElementById('topho')) {
                document.getElementById('topho').removeAttribute('class');
                document.getElementById('topho').setAttribute('src', apijs.dialogue.image.src);
            }
        }, false);
    };
}

Le paramètre URL contient une adresse du genre : http://localhost/apijs/uploadfile.php?image=5f1ce0b3
Voici la fonction qui est exécutée lors de l'appel de l'adresse précédente (l'image est envoyée au navigateur puis supprimée) :

$file = './docs/tmp/'.$_GET['image'].'.png';
header('Content-Type: image/png');
header('Content-Length: '.filesize($file));
readfile($file);
unlink($file);

Le problème est le suivant : sous Chromium/Chrome/Safari, l'image ne s'affiche pas, alors que sous Firefox et Opera, il n'y a pas de problème.

J'ai essayé d'afficher le contenu du paramètre URL via un alert, l'adresse est bien valide, et l'image existe bien dans le dossier docs/tmp.
De ce que j'en comprends pour le moment, c'est que Chromium envoi deux requêtes, une pour le fun (qui n'apparaît pas dans la console), et une seconde (qui apparaît dans la console) pour récupérer l'image... qui n'existe plus.

Une idée ?

Dernière modification par luigifab (Le 07/09/2011, à 23:36)


Free Ukraine!

Hors ligne

#2 Le 14/05/2011, à 00:10

luigifab

Re : [Résolu / JavaScript] Préchargement d'image avec l'objet Image

J'ai trouvé le pourquoi du comment !
Mieux, j'ai également trouvé comment faire croire au navigateur qu'un fichier existe sur le serveur alors que ce n'est pas le cas.

Tout est dans l'en-tête HTTP de la réponse.

Pour information, l'adresse de mon image préchargée via JavaScript est : http://localhost/apijs/uploadfile.php?image=0b5cfecd
Celle-ci est immédiatement supprimée après sa lecture.


1) Script PHP et réponse HTTP avant modification

if (isset($_GET['image']) && is_file('./docs/tmp/'.$_GET['image'].'.png') && is_readable('./docs/tmp/'.$_GET['image'].'.png')) {

    $file = './docs/tmp/'.$_GET['image'].'.png';

    header('Content-Type: image/png');
    header('Content-Length: '.filesize($file));

    readfile($file);
    unlink($file);
}
HTTP/ 1.1 200 OK
X-Powered-By: PHP/5.2.10-2ubuntu6.10
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Type: image/png
Content-Length: 251928
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Date: Fri, 13 May 2011 21:08:41 GMT
Server: lighttpd/1.4.22

Trois problèmes dans la réponse : Cache-Control, Pragma et Expires.

Webkit n'aime pas bien et n'affiche pas mon image, car il doit, une fois le préchargement terminé, essayer de charger l'image une deuxième fois lors de son affichage.


2) Script PHP et réponse HTTP après la modification qui change tout

if ((isset($_GET['image']) && is_file('./docs/tmp/'.$_GET['image'].'.png') && is_readable('./docs/tmp/'.$_GET['image'].'.png')) || (isset($_GET['image']) && isset($_SESSION['imageTag']) && isset($_SESSION['imageExp']) && ($_SESSION['imageExp'] > time()) AND ($_GET['image'] === $_SESSION['imageTag']))) {

    $file = './docs/tmp/'.$_GET['image'].'.png';

    if (is_file($file)) {

        $_SESSION['imageTag'] = $_GET['image'];
        $_SESSION['imageExp'] = time() + 500;

        header('HTTP/ 1.1 200 OK');
        header('Cache-Control: public');
        header('Pragma: public');

        header('Content-Type: image/png');
        header('Content-Length: '.filesize($file));
        header('Expires: '.gmdate('D, d M Y H:i:s', $_SESSION['imageExp']).' GMT');

        readfile($file);
        unlink($file);
    }
    else {
        header('HTTP/ 1.1 304 Not Modified');
        header('Cache-Control: no-cache');
        header('Pragma: no-cache');
    }
}
HTTP/ 1.1 200 OK
X-Powered-By: PHP/5.2.10-2ubuntu6.10
Cache-Control: public
Pragma: public
Content-Type: image/png
Content-Length: 251928
Expires: Fri, 13 May 2011 21:56:27 GMT
Date: Fri, 13 May 2011 21:48:06 GMT
Server: lighttpd/1.4.22

À bien noter dans la réponse : Cache-Control, Pragma et Expires.
Webkit préfère cette réponse puisqu'il affiche bien mon image.


3) Réponse HTTP bonus après la modification précédente qui change tout

HTTP/ 1.1 304 Not Modified
X-Powered-By: PHP/5.2.10-2ubuntu6.10
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache
Pragma: no-cache
Date: Fri, 13 May 2011 21:48:23 GMT
Server: lighttpd/1.4.22

Bien que l'image n'existe plus sur le serveur, on fait croire au navigateur que l'image existe encore un certains temps...
J'ai pas dit que c'était forcément utile.


En ce vendredi 13 qui se termine, je suis fier d'avoir vaincu l'ordinateur big_smile.
S'il y a des questions, je suis là.

Dernière modification par luigifab (Le 14/05/2011, à 14:32)


Free Ukraine!

Hors ligne