Mav: Bild neu laden lassen per header('Refresh:');

Ich möchte ein per PHP dynamisch generiertes Bild per header('Refresh:...') vom Client automatisch neu laden lassen.

Der entsprechende PHP-Code könnte (stark vereinfacht) zum Beispiel so aussehen:

bild.php:

<?php  
$num = $_GET['n'];  
$img = imagecreate(100, 100);  
$c0 = imagecolorallocate($img, 255, 255, 255);  
$c = imagecolorallocate($img, 0, 0, 0);  
imagettftext($img, 30, 0, 50, 50, $c, 'myfont.ttf', $num);  
header('Cache-Control: no-cache');  
header('Pragma: no-cache');  
header('Content-Type: image/png');  
if ($num > 0) {  
    header('Refresh:1;url=/bild.php?n=' . ($num - 1));  
}  
imagepng($img);

Funktioniert soweit auch wunderbar unter den folgenden beiden Bedingungen:
1. Client blockiert Header-Refresh nicht (das Problem will (und kann) ich nicht lösen)
2. das Bild wird direkt aufgerufen (also nicht in einer Seite eingebettet)

Wird das Bild in eine HTML-Datei eingebettet, dann funktioniert das ganze nicht mehr:

test.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>Beispiel</title>  
</head>  
<body>  
<img src="/bild.php?n=10" alt="">  
</body>  
</html>

Hat jemand eine Idee, wie man das Problem anders angehen könnte, oder wie man das Beispiel von oben verändern müsste, damit es auch aus einer HTML-Seite herraus funktioniert? Vieleicht einfach nur ein zusätzlicher Header, der gesendet werden muss?
Bitte keine Lösung per Javascript...das bekomme ich auch selber hin, ist jedoch meine letzte Wahl.

Danke im Vorraus.
--Mav

  1. hi,

    Deine header() Funktionen machen schon das was sie sollen, aber nicht das was Du willst, das ist das Problem. Schau dir mal die HTTP-Header an, die das Script ausgibt. header(refresh:...) ist ein Wrapper für header(location:...) und das Umleiten funktioniert nur, wenn vorher der HTTP-Header nicht abgechlossen wurde, was bei Dir offensichtlich der Fall ist, weil der Content-Type vorher schon ausgegeben wurde.

    Rolf

    1. Hallo Rolf,

      Schau dir mal die HTTP-Header an, die das Script ausgibt.

      php 5.3.0 per shell im Test:

      $ echo "<?php header('Refresh: 1;url=bla'); ?>" | php-cgi

      Status: 200 OK
      Refresh: 1;url=bla
      Content-type: text/html; charsetz=iso-8859-1

      header(refresh:...) ist ein Wrapper für header(location:...)

      Dazu liegen mir (insbesondere nach meinem Test) keine Anhaltspunkte vor.

      und das Umleiten funktioniert nur, wenn vorher der HTTP-Header nicht abgechlossen wurde,

      Bis dahin gehe ich noch als allgemein gültige Aussage mit.

      was bei Dir offensichtlich der Fall ist,

      Soweit ist das mindesten nicht offensichtlich. Einzige Möglichkeit wäre nur, das gd.so/gd.dll nicht eingebunden wurde, was _eben nicht offensichtlich_ dem Code zu entnehmen ist.

      weil der Content-Type vorher schon ausgegeben wurde.

      Lassen wir die Statuszeile als Sonderfall außen vor, gibt es laut HTTP-Spezifikation keine Reihenfolge für Header. (Auch auf PHP-Ebene gibt es diese nicht. Hier lassen sich gleichlautende HTTP-Header sogar überschreiben. Dazu hat die Funktion header() seit Version 4.0.4 den zweiten, optionalen Parameter. Intern werde also alle Header so lange durch PHP selbst gesammelt und können überschrieben werden, bis deren Aussenden an den Webserver zwangsläufig wird, weil die erste inhaltliche Ausgabe der zu servierenden Ressource dem Webserver übergeben werden soll.)

      Gruß aus Berlin!
      eddi

  2. Hallo erstmal!

    Hat jemand eine Idee, wie man das Problem anders angehen könnte, oder wie man das Beispiel von oben verändern müsste, damit es auch aus einer HTML-Seite herraus funktioniert? Vieleicht einfach nur ein zusätzlicher Header, der gesendet werden muss?
    Bitte keine Lösung per Javascript...das bekomme ich auch selber hin, ist jedoch meine letzte Wahl.

    Es ist erstaunlich, dass Du Javascript als Letzte Wahl bezeichnest, wo Du völlig wider dem HTTP-Standard (RFC 2616) einen Header sendest willst, der - formal betrachtet - sogar zu einer Fehlermeldung im Client sorgen sollte; deren verlässliche Interpretation durch den Client jedenfalls aber ein weit größeres Problem darstellt, als deaktiviertes Javascript es auch nur ansatzweise sein könnte.

    Gruß aus Berlin!
    eddi