Generiertes PDF an IE übertragen

Hallo,
ich muss mal wieder ein uraltes Thema aufwärmen. Vielleicht hat sich da ja
mittlerweile irgendetwas Sinnvolles getan:

Ich habe eine PHP-Webapplikation, die - nach einigen Eingaben - ein
PDF-Dokument generiert. An dieser Stelle steht für normale Browser

header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename=Mein.pdf");
echo `/irgendwo/machmalPdf param1 param2 ... paramN`;

Das reicht für alle richtigen Browser ... Nur nicht für beliebige
Inkarnationen des IE (als ich das schrieb gab's gerade den 5.5). Für
die gibt es dann zwei Extrawürste.

Gemeinsam:

$tmpname = "$_SERVER[DOCUMENT_ROOT]/tmp/Mein-".session_id().".pdf";
system("/irgendwo/machmalPdf param1 param2 ... paramN >$tmpname");

IE 5:

header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename=Mein.pdf");
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Length: '.filesize($tmpname));
readfile($tmpname);
unlink($tmpname);

andere IEs:

$secure = ($_SERVER['SERVER_PORT'] == 443) ? 's' : '';
header("Location: http$secure://$_SERVER[HTTP_HOST]/tmp/Mein-".
session_id().".pdf");

Dann brauche ich für die übrig bleibenden PDFs der anderen IEs nur noch
einen Lumpensammler (cron-Job), der alle Stunde alle alten PDFs in die
Tonne tritt.

Dieses schwachsinnige aber effektive Verfahren hat nun mehrere Jahre
funktioniert aber so langsam häufen sich die Meldungen von Leuten, die
wieder mal - meist nur sporadisch - weiße Seiten in Ihrem IE angezeigt
bekommen.

Deshalb meine Frage:
Wie ist der heutige Stand der Technik, um einen IE (zurück bis 5.0 reicht
wohl inzwischen) aus einem PHP-Skript heraus zur Annahme eines PDFs zu
überreden?

mfg Volker
volker [ Mi, 19 September 2007 18:39 ] [ ID #1824446 ]

Re: Generiertes PDF an IE übertragen

Volker Boehm wrote:

Hallo,

> IE 5:
>
> header("Content-Type: application/pdf");
> header("Content-Disposition: attachment; filename=3DMein.pdf");
> header("Pragma: public");
> header("Cache-Control: must-revalidate, post-check=3D0, pre-check=
=3D0");
> header('Content-Length: '.filesize($tmpname));
> readfile($tmpname);
> unlink($tmpname);

Weitere Möglichkeiten

- Beim Apache zusätzlich mod_rewrite benutzen, um eine URL mit .pdf
als Endung zu haben.

- Generierte Datei mit .pdf als Endung auf dem Server speichern und
per header('Location: http://...') darauf umleiten (veraltete
Dateien automatisch löschen).

- Ansehen, was bei einem statischen .pdf-Dokument an den Browser
geschickt wird und dieses möglichst exakt inklusive URL kopieren
(Firefox Liveheaders, http://web-sniffer.net/).


tschuess
[|8:) http://www.sven-drieling.de/
Sven Drieling [ Mi, 19 September 2007 19:00 ] [ ID #1824450 ]

Re: Generiertes PDF an IE übertragen

Am Wed, 19 Sep 2007 19:00:51 +0200 schrieb Sven Drieling:

> Volker Boehm wrote:
>
>> IE 5:
>>
>> header("Content-Type: application/pdf");
>> header("Content-Disposition: attachment; filename=Mein.pdf");
>> header("Pragma: public");
>> header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
>> header('Content-Length: '.filesize($tmpname));
>> readfile($tmpname);
>> unlink($tmpname);
>
> Weitere Möglichkeiten
>
> - Beim Apache zusätzlich mod_rewrite benutzen, um eine URL mit .pdf
> als Endung zu haben.

Wenn der Benutzer das letzte Formular ausgefüllt hat und den Submit-Button
drückt, ist ja noch gar nicht sicher, dass er überhaupt ein PDF bekommt.
Das kriegt er ja nur, wenn seine Eingabe fehlerfrei war; sonst bekommt er
eine HTML-Seite mit einer Fehlermeldung.
Also kann das Ziel des letzten Formulars nicht 'irgendwas.pdf' lauten,
sondern eigentlich nur 'irgendwas.php' und wenn der MIME-Type dann
'application/pdf' lautet, ist's halt ein PDF. Aber für so was ist ein IE
halt zu blöd.

> - Generierte Datei mit .pdf als Endung auf dem Server speichern und
> per header('Location: http://...') darauf umleiten (veraltete
> Dateien automatisch löschen).

Das ist ja genau das Verfahren, das ich für 'andere IEs' anwende und das
bei einigen IEs (heute selber mit einem IE 6.0 und Acrobat Reader 7
getestet) in die Hose geht. Mit einem Acrobat 8 ging's dann übrigens
wieder (und das PDF ist aus LaTex mit pdflatex als PDF 1.4.7 generiert;
also braucht man dazu keinen Acrobat Reader 8).

> - Ansehen, was bei einem statischen .pdf-Dokument an den Browser
> geschickt wird und dieses möglichst exakt inklusive URL kopieren
> (Firefox Liveheaders, http://web-sniffer.net/).

Da fehlt mir wohl noch die Gebrauchsanleitung zu.
Wenn ich http://web-sniffer.net/ aufrufe und in die dortige URL-Zeile eine
PDF-URL eingebe, bekomme ich folgende Header angezeigt:

HTTP Status Code: HTTP/1.1 200 OK
Date: Wed, 19 Sep 2007 17:31:36 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) mod_python/3.1.3
Python/2.3.5 PHP/4.3.10-18
Last-Modified: Mon, 15 Mar 2004 23:27:51 GMT
ETag: "befb9-ff743-d47dabc0"
Accept-Ranges: bytes
Content-Length: 1046339
Connection: close
Content-Type: application/pdf

Und was sollte ich jetzt als PHP-Header-Anweisungen zu meinen PDF
dazuschreiben, damit auch ein IE das kapiert?

Ich glaube das Hauptproblem liegt darin, dass bei Herrn Gates alles an der
Extension aufgehängt ist und ihm der MIME-Type egal ist. Beim Aufruf der
Seite steht aber noch gar nicht fest, was für ein Typ denn zurückkommen
wird.

Hat noch jemand eine zündende Idee?

mfg Volker
volker [ Mi, 19 September 2007 20:14 ] [ ID #1824457 ]

Re: Generiertes PDF an IE übertragen

..oO(Volker Boehm)

>Am Wed, 19 Sep 2007 19:00:51 +0200 schrieb Sven Drieling:
>
>> - Beim Apache zusätzlich mod_rewrite benutzen, um eine URL mit .pdf
>> als Endung zu haben.
>
>Wenn der Benutzer das letzte Formular ausgefüllt hat und den Submit-Button
>drückt, ist ja noch gar nicht sicher, dass er überhaupt ein PDF bekommt.
>Das kriegt er ja nur, wenn seine Eingabe fehlerfrei war; sonst bekommt er
>eine HTML-Seite mit einer Fehlermeldung.

Wie wärs im Erfolgsfall mit einem 302-Redirect auf ein Script mit .pdf-
Endung, welches dann das fertige Dokument liefert?

>Also kann das Ziel des letzten Formulars nicht 'irgendwas.pdf' lauten,
>sondern eigentlich nur 'irgendwas.php' und wenn der MIME-Type dann
>'application/pdf' lautet, ist's halt ein PDF. Aber für so was ist ein IE
>halt zu blöd.

Ja, leider. Und zwar grundsätzlich, nicht nur bei PDFs.

Micha
Michael Fesser [ Mi, 19 September 2007 20:29 ] [ ID #1824459 ]

Re: Generiertes PDF an IE übertragen

Am Wed, 19 Sep 2007 20:29:00 +0200 schrieb Michael Fesser:

> .oO(Volker Boehm)
>
>>Am Wed, 19 Sep 2007 19:00:51 +0200 schrieb Sven Drieling:
>>
>>> - Beim Apache zusätzlich mod_rewrite benutzen, um eine URL mit .pdf
>>> als Endung zu haben.
>>
>>Wenn der Benutzer das letzte Formular ausgefüllt hat und den Submit-Button
>>drückt, ist ja noch gar nicht sicher, dass er überhaupt ein PDF bekommt.
>>Das kriegt er ja nur, wenn seine Eingabe fehlerfrei war; sonst bekommt er
>>eine HTML-Seite mit einer Fehlermeldung.
>
> Wie wärs im Erfolgsfall mit einem 302-Redirect auf ein Script mit .pdf-
> Endung, welches dann das fertige Dokument liefert?

Auch 'ne schöne Idee :-)
Ich hab gerade mal
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
konsultiert, um nachzulesen, was genau ein 302 eigentlich bedeutet. Und da
stand dann
10.3 Redirection 3xx
... The action required MAY be carried out by the user agent without
interaction with the user if and only if the method used in the second
request is GET or HEAD.
...
10.3.3 302 Found
...
If the 302 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, ...

Wenn der Browser sich daran hält, wird der Benutzer nach dem
entscheidenden Klick nochmal irgendetwas - für die meisten wohl
Unverständliches - gefragt.

Aber wie wär's denn mit einem '201 Created'. Das ist so ungefähr das
Gleiche nur ohne Einschränkungen und mit der Aussage:
Ich habe dir ein Dokument gemäß deines Requestes generiert. Du kannst
es dir dort (neue URI) abholen.

Und hinter dieser (PDF-)URI verbirgt sich dann über mod_rewrite wieder
ein PHP-Skript.

Oder ist ein IE für sowas auch wieder zu blöd?

>>Also kann das Ziel des letzten Formulars nicht 'irgendwas.pdf' lauten,
>>sondern eigentlich nur 'irgendwas.php' und wenn der MIME-Type dann
>>'application/pdf' lautet, ist's halt ein PDF. Aber für so was ist ein IE
>>halt zu blöd.
>
> Ja, leider. Und zwar grundsätzlich, nicht nur bei PDFs.

Ja, leider. Womit ham' wir das verdient?

mfg Volker
volker [ Mi, 19 September 2007 20:54 ] [ ID #1824461 ]

Re: Generiertes PDF an IE übertragen

..oO(Volker Boehm)

>Am Wed, 19 Sep 2007 20:29:00 +0200 schrieb Michael Fesser:
>
>> Wie wärs im Erfolgsfall mit einem 302-Redirect auf ein Script mit .pdf-
>> Endung, welches dann das fertige Dokument liefert?
>
>Auch 'ne schöne Idee :-)
>Ich hab gerade mal
> http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
>konsultiert, um nachzulesen, was genau ein 302 eigentlich bedeutet. Und da
>stand dann
>[...]
> If the 302 status code is received in response to a request other
> than GET or HEAD, the user agent MUST NOT automatically redirect the
> request unless it can be confirmed by the user, ...
>
>Wenn der Browser sich daran hält, wird der Benutzer nach dem
>entscheidenden Klick nochmal irgendetwas - für die meisten wohl
>Unverständliches - gefragt.

Hab ich bisher nie erlebt. Direkt im Anschluß an obiges steht nämlich
auch noch:

| Note: RFC 1945 and RFC 2068 specify that the client is not allowed to
| change the method on the redirected request. However, most existing
| user agent implementations treat 302 as if it were a 303 response,
| Location performing a GET on the field-value regardless of the
| original request method. The status codes 303 and 307 have been added
| for servers that wish to make unambiguously clear which kind of
| reaction is expected of the client.

Der 303 wäre somit eigentlich korrekt, dürfte aber weit weniger
unterstützt werden als 302.

Ich benutze sowas auch bei meiner normalen Formularverarbeitung. Nach
dem letzten POST-Request und der erfolgten Verarbeitung wird der Browser
per Location-Header nochmals auf die gleiche Seite "umgeleitet". Das
verhindert, daß der Besucher beim Vor- und Zurückspringen durch den
Seitenverlauf irgendwann eine Meldung bekommt wie "POST data expired".

>Aber wie wär's denn mit einem '201 Created'. Das ist so ungefähr das
>Gleiche nur ohne Einschränkungen und mit der Aussage:
> Ich habe dir ein Dokument gemäß deines Requestes generiert. Du kannst
> es dir dort (neue URI) abholen.

Wäre vlt. auch eine Möglichkeit, aber gerade bei diesen etwas
"esoterischen", sprich kaum genutzten Statuscodes, dürften Probleme
vorprogrammiert sein.

Micha
Michael Fesser [ Mi, 19 September 2007 21:18 ] [ ID #1824463 ]

Re: Generiertes PDF an IE übertragen

Volker Boehm schrieb:

> Dieses schwachsinnige aber effektive Verfahren hat nun mehrere Jahre
> funktioniert aber so langsam häufen sich die Meldungen von Leuten, di=
e
> wieder mal - meist nur sporadisch - weiße Seiten in Ihrem IE angezeig=
t
> bekommen.

Empfehle diesen Leuten die Verwendung eines Browsers. Wenn alle das
täten, statt immer wieder die Macken des IE zu kompensieren, wäre die=

(Web-)Welt inzwischen sehr viel einfacher.

> Deshalb meine Frage:
> Wie ist der heutige Stand der Technik, um einen IE (zurück bis 5.0 re=
icht
> wohl inzwischen) aus einem PHP-Skript heraus zur Annahme eines PDFs zu
> überreden?

Ich verstecke das Skript mittels mod_rewrite. Daher weiß der IE nicht,
dass er keine gespeicherte Datei bekommt. Das klappt mit allen IEs und
allen Browsern und bedarf keinerlei Verrenkungen im Skript.

MfG
Niels

--
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------
Niels Braczek [ Do, 20 September 2007 00:15 ] [ ID #1824469 ]

Re: Generiertes PDF an IE übertragen

Volker Boehm wrote:

Hallo,

> Wenn der Benutzer das letzte Formular ausgefüllt hat und den Submit=
-Button
> drückt, ist ja noch gar nicht sicher, dass er überhaupt ein PDF b=
ekommt.
> Das kriegt er ja nur, wenn seine Eingabe fehlerfrei war; sonst bekomm=
t er
> eine HTML-Seite mit einer Fehlermeldung.

Hmm, ähnlich wie beim Download auf Sourceforge immer erst eine HTML-=
Seite
ausgeben und von dieser per Meta-Refresh auf's PDF umleiten: 'Falls
der Download in wenigen Sekunden nicht automatisch startet, dann
bitte hier klicken.' bzw. auf's Meta-Refresh gänzlich verzichtet: 'D=
as
PDF wurden nach ihren Wünschen generiert' und darunter einen große=
n
"DOWNLOAD PDF"-Button anbieten.


Oder für das Formular grundsätzlich .pdf als Endung der URL
benutzten und die Seite mal als text/html und mal application/pdf
ausliefern. Würde ich zwar nicht benutzen/empfehlen wäre aber
interessant auszuprobieren wie die Browser sich damit verhalten.

>> - Generierte Datei mit .pdf als Endung auf dem Server speichern und=

>> per header('Location: http://...') darauf umleiten (veraltete
>> Dateien automatisch löschen).
>
> Das ist ja genau das Verfahren, das ich für 'andere IEs' anwende un=
d das
> bei einigen IEs (heute selber mit einem IE 6.0 und Acrobat Reader 7
> getestet) in die Hose geht. Mit einem Acrobat 8 ging's dann übrigen=
s
> wieder (und das PDF ist aus LaTex mit pdflatex als PDF 1.4.7 generier=
t;
> also braucht man dazu keinen Acrobat Reader 8).

Wenn der Fehler auf der Client Seite liegt, dann kann er nur da
behoben werden.

>> - Ansehen, was bei einem statischen .pdf-Dokument an den Browser
>> geschickt wird und dieses möglichst exakt inklusive URL kopiere=
n
>> (Firefox Liveheaders, http://web-sniffer.net/).
>
> Da fehlt mir wohl noch die Gebrauchsanleitung zu.
> Wenn ich http://web-sniffer.net/ aufrufe und in die dortige URL-Zeile=
eine
> PDF-URL eingebe, bekomme ich folgende Header angezeigt:

> Und was sollte ich jetzt als PHP-Header-Anweisungen zu meinen PDF
> dazuschreiben, damit auch ein IE das kapiert?

Ist die Variante, die nur bei URLs mit .pdf als Endung geht.

> Ich glaube das Hauptproblem liegt darin, dass bei Herrn Gates alles a=
n der
> Extension aufgehängt ist und ihm der MIME-Type egal ist.

Eventuell lässt sich der IE mit einem angehängten dummy=3Ddokument=
..pdf
überreden.

http://www.example.com/PDFDoc.php?dummy=3Ddokument.pdf

oder

http://www.example.com/PDFDoc.php/dokument.pdf



http://groups.google.com/group/de.comp.lang.php.netzprotokol le/msg/a1b2=
cc4858a21d68
hat zusätzlich noch den Tipp filename auch beim Content-Typ anzuhä=
ngen

header("Content-Type: application/octet-stream;filename=3D$dl_name")=
;
header("Content-Disposition: attachment;filename=3D$dl_name");


tschuess
[|8:) http://www.sven-drieling.de/
Sven Drieling [ Do, 20 September 2007 10:29 ] [ ID #1825381 ]
PHP » de.comp.lang.php.misc » Generiertes PDF an IE übertragen

Vorheriges Thema: Methoden Namen feststellen
Nächstes Thema: Suche PHP-Notizzettel