Forum Programmation.php Script d'affichage d'une image

Posté par  .
Étiquettes :
0
30
déc.
2007
Bonjour,

j'ai un problème très désagréable: lors de l'appel d'un simple script qui affiche une image, Firefox ou Konqueror affiche aléatoirement l'image ou les données brutes correspondant à cette image.

mon fichier get_file.php contient le code suivant:

[?php
$file=get_file_data_by_id($_GET["id"]);

header("Cache-Control: must-revalidate");
header("Content-Description: File Transfer");
header("Content-Type: ".$file["mime_type"]);
header('Content-Length: '.filesize($file["path"]));
header("Content-Disposition: filename='".$file["name"]."'");
header("Content-Transfer-Encoding: binary");

@readfile($file["path"]);
exit();
?]


j'ai bien vérifié qu'aucun caractère n'est envoyé avant ou après les balises d'ouverture et de fermeture de php.
Ce fichier est appelé dans l'attribut src d'une balise img, elle-même incluse dans une balise a :

[a href='get_file.php?id=8' target='_blank']
[img src='get_file.php?id=8' alt='fichier'/]
[/a]


La page incluant la balise img affiche aléatoirement l'image demandée, ou le texte de l'attribut alt.
La page get_file.php appelée directement affiche aléatoirement l'image demandée ou les données brutes affichées sous forme de texte.

Après moultes recherche je ne vois pas d'explications, si ce n'est un problème au niveau du cache du serveur et/ou du navigateur que je ne sais pas identifié

merci de vos éclairages
  • # content-type

    Posté par  . Évalué à 1.

    j'avais fais des essais avec cette methode...

    le seul moyen que ca fonctionne correctement etait que ce soit une page autonome.

    impossible de l'inclure dans une autre page. => impossible d'en faire un lien avec une vignette par exemple

    par contre vu que tu recuperes/calcules le chemin du fichier, tu peux peut-etre faire la recherche du chemin puis inclure ce chemin dans ton < a href=$chemin >< img src =$chemin> < /a>
    • [^] # Re: content-type

      Posté par  . Évalué à 1.

      Pourtant tous les commentaires sur la page d'aide de readfile, ainsi que tous les tutoriaux sur lesquels j'ai pu tombé, indiquent que cette methode est valable. Il doit bien y avoir un paramètre qui me glisse entre les doigts !

      Le but est d'utiliser des fichiers stockés sur un fs inaccessible au serveur http, donc la solution d'inclure le chemin directement dans les balises n'est pas satisfaisante
  • # ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

    Posté par  . Évalué à 2.

    la plupart des (administrateurs de) forums et autres acceptent de moins en moins des images à paramètres pour diverses raisons de sécurité. idem pour mod_security

    sinon, pour mes conneries en php à l'époque, je n'ai jamais eu besoin que de Header("Content-type: image/jpeg"); (ou autre type). en particulier, je suis assez sûr que le serveur Web se démerde assez bien ensuite avec ton fichier et n'a pas besoin de ton Content-Length
    • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

      Posté par  . Évalué à 1.

      mon id est un numero d'identifiant unique dans une base mysql, donc si on y met autre chose qu'un integer, il y a une redirection vers une page d'erreur, et si on y met un nombre au pif, au pire on affichera un fichier dont on ne sait pas a quoi il conrrespondra

      en ne laissant que le content-type, j'ai le meme comportement.
      Ce qui m'ennuie le plus, c'est que pour deux pages differentes comportant le meme code (image + liens vers l'image) j'ai deux comportements differents: dans un cas, le navigateur interprete correctement ce qui lui est envoyé, dans l'autre il ne reconnait pas l'image et affiche les donnees brutes :(
      • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

        Posté par  . Évalué à 1.


        Ce qui m'ennuie le plus, c'est que pour deux pages differentes comportant le meme code (image + liens vers l'image) j'ai deux comportements differents: dans un cas, le navigateur interprete correctement ce qui lui est envoyé, dans l'autre il ne reconnait pas l'image et affiche les donnees brutes :(


        tes 2 pages ne contiennent-elles que ce code là ?

        car il faut qu'elle ne contiennent que ca si tu veux utiliser le contet-type

        tu ne peux donc pas avoir une creation de page normal genre forum ou gallerie, si tu envoie ensuite ton content-type...
        ca ne marchera pas.
        • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

          Posté par  . Évalué à 1.

          tu m'as mal compris: j'ai d'un coté le fichier get_file.php qui dont j'ai fourni le code, et de l'autre deux fichiers appelant get_file.php via l'attribut href d'une balise [a] et l'attribut src d'une balise [img]. Ces deux fichiers ont un comportement different: l'un affiche correctement l'image et le lien renvoie correctement une page ne contenant que l'image, et l'autre affiche le contenu de l'attribut alt de la balie [img], et le lien renvoie les données brutes de l'image sous forme de texte.
          • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

            Posté par  . Évalué à 1.

            Je viens de m'apercevoir de qqchose d'encore plus bizarre: avec Firefox , sur la page qui affiche le contenu de l'attribut alt, l'image est d'abord affichée pour etre ensuite remplacée par le contenu de l'attribut alt ... c'est à n'y rien comprendre.

            On dirait que les données sont envoyées correctement, puis qu'à un moment il y a un probleme qui fait prendre la décision au navigateur de considerer ce flux comme invalide et d'afficher le contenu de la balise alt
            • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

              Posté par  . Évalué à 1.

              Je continue a me causer au cas ou cela serve à quelqu'un: j'ai reperer un retour chariot au debut de la page qui affiche les données brutes. De ce fait, l'image n'est pas reconnue ....
              il ne reste plus qu'a determiner d'ou vient ce retour chariot puisque c'est normalement le meme fichier get_file.php qui est censée generer la page qui affiche les données brutes et celle qui affiche correctement l'image

              stay tuned !
              • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

                Posté par  . Évalué à 1.

                probleme resolu: un session_start() envoyait un retour chariot intempestif ...
                mais je ne sais toujours pas pourquoi ce session_start renvoyait ce retour chariot quand on venait de la page a probleme et pas de l'autre !
                • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

                  Posté par  . Évalué à 1.

                  si ca marche tu as beaucoup de chance

                  car dans ton get_file tu redefinis le header() du fichier html que tu affiches...

                  ce qui n'est normalement pas tres "propre" comme technique.

                  mais si ca marche et que le serveur comme le navigateur le laisse faire pourquoi pas.

                  quant au retour chariot intempestif, c'est une bonne question.
                  • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

                    Posté par  . Évalué à 1.

                    gni ?
                    quel fichier html ?
                    je n'affiche aucun fichier html, j'envoie simplement le contenu d'un fichier correspondant à un identifiant unique, le tout précédé d'une entete http pour que le navigateur comprenne ce qu'il recoit
                    • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

                      Posté par  . Évalué à 1.

                      le fichier get_file ne fait effectivement qu'afficher une image

                      mais le code
                      <a href = get_file.php?xxxx><img src=get_file.php?xxxx>

                      doit bien etre inclus dans une page html pour etre lu...
                      et censé affiché l'image et le lien

                      donc ton navigateur recoit un premier header pour la page
                      que tu modifie à chaque appel de get_file.php
                      • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

                        Posté par  . Évalué à 1.

                        Je ne suis pas un specialiste du sujet, mais d'après ce que je comprends:
                        - le navigateur recoit la page avec le HTML contenant le lien et la balise img
                        - il demande au serveur web de lui envoyer l'image indiquée par l'attribut src
                        - le serveur va chercher le fichier, et determine qu'il s'agit d'un fichier php; il delegue donc le traitement de cette requete à PHP
                        - mon script est interprete par PHP et envoie le header HTTP indiquant que ce qui suit est un fichier binaire avec, par exemple, le mime type image/jpeg.
                        - le navigateur recoit l'information et conclue que le flux de données recu est en accord avec la sémantique de la balise img: il affiche donc l'image.

                        Si l'attribut src avait contenu directement l'adresse d'une image, le serveur web aurait lui meme construit le header HTTP correspondant et envoyée les données, de la meme manière que le fait mon script PHP.

                        L'intervention d'un connoisseur éclairé pourrait nous apporté une réponse satisfaisante
                      • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

                        Posté par  (site web personnel) . Évalué à 1.

                        Tu fais un erreur là NeoX, la récupération de la page et celle de l'image sont faites par deux requêtes HTTP bien distinctes par le client; i n'y a donc bien qu'un seul header Content-Type à chaque fois.
                        Lorsqu'un navigateur charge une page, il charge d'abord le fichier source puis ferme la connexion et en ouvre une autre à chaque ressource contenue dans le source (que ce qoit une image, une video, ...) (SAuf dans le cas de l'utilisation de keep-alive, masi celà reste tout de même des requêtes bien differentes);
                  • [^] # Re: ne pas utiliser de ?id=12345 mais des numéros uniques 12345.gif

                    Posté par  . Évalué à 1.

                    le mot de la fin: session_start() n'était qu'indirectement responsable !
                    Le fautif était un fichier définissant une classe automatiquement incluse par une fonction __autoload, elle même appelée par session_start parce qu'une de mes variables de session était une instance de cette classe ... et ce fichier contenait un retour charriot après les balises PHP

                    CQFD vous pouvez retournez à vos fourneaux !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.