Johannes F.: Externes File zum Download

Hallo SelfHTMLer,

ich möchte eine externe Datei, von der ich die URL gegebene habe als Download ausgeben mit PHP.

Zurzeit verwende ich dazu folgendes:

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="download"');
header('Content-Length: ' . $content_length);
die(file_get_contents($url));

Wie kann ich das komfortabler/besser erreichen?
Wenn ich es richtig sehe muss bei meiner Lösung erst mein Server die Datei holen um sie dann als download anbieten zu können. Kann ich erreichen, dass dem Client direkt die Datei als Download angeboten wird?

Viele Grüße

Johannes F.

  1. Hallo,

    Wenn ich es richtig sehe muss bei meiner Lösung erst mein Server die Datei holen um sie dann als download anbieten zu können. Kann ich erreichen, dass dem Client direkt die Datei als Download angeboten wird?

    ja selbstverständlich: das Verfahren dazu benötigt überhaupt keine Programmiersprache, das geht mit HTML der allerersten Stunde. Verwende einfach einen Link.

    Freundliche Grüße

    Vinzenz

    1. Der öffnet allerdings nicht zum Download.. example.com/test.html wird nicht zum Download geöffnet.

      1. Mahlzeit Johannes F.,

        Der öffnet allerdings nicht zum Download.. example.com/test.html wird nicht zum Download geöffnet.

        Klar - weil ein Browser ja dafür da ist, Dateien vom Typ "text/html" anzuzeigen.

        Im Übrigen kannst Du den/die Browser Deiner Benutzer nicht dazu *zwingen* irgendetwas zu tun. Du kannst nicht verlässlich erreichen, dass bestimmte Dateien (abhängig von ihrer Dateiendung, ihres MIME-Types, ihres Inhalts o.ä.) auf eine bestimmte - und überall gleiche - Art und Weise behandelt werden.

        Du kannst lediglich Empfehlungen aussprechen bzw. den Browser darum bitten, die im Folgenden ausgelieferte Datei z.B. nicht inline anzuzeigen, sondern zum Speichern anzubieten ... verhindern kannst Du irgendein Verhalten jedoch nicht.

        Akzeptiere das.

        MfG,
        EKKi

        --
        sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
      2. Hi!

        Der öffnet allerdings nicht zum Download.. example.com/test.html wird nicht zum Download geöffnet.

        "Zum Download bitte einen Rechtsklick auf den Link ausführen und die Funktion 'Ziel speichern unter' aus dem Menü verwenden" oder so ähnlich.

        Man muss unwissenden Anwendern auch mal beibringen, wie etwas geht, anstatt ihnen selbst solch einen simplen Zweitklick abnehmen zu wollen.

        Lo!

        1. "Zum Download bitte einen Rechtsklick auf den Link ausführen und die Funktion 'Ziel speichern unter' aus dem Menü verwenden" oder so ähnlich.

          So eine Antwort hätte ich von dir nicht erwartet :)

          Man muss unwissenden Anwendern auch mal beibringen, wie etwas geht, anstatt ihnen selbst solch einen simplen Zweitklick abnehmen zu wollen.

          Ja, aber hier stehe ich eher auf der Seite, dass man das nicht auf der Website tun sollte.

          An einer Ampel steht ja auch kein Schild "Fahren sie bei grünem Licht" :)

          Grundfunktionen eines Browsers im Frontend einer Website direkt zu erklären finde ich falsch. Irgendwo ein kleines Fragezeichen mit einem Tooltip oder einem Link zu einer Hilfe-Seite ist ok, aber direkt unter oder nebene einem Bild/Link/etc. finde ich äußerst fragwürdig.

          1. Hi!

            "Zum Download bitte einen Rechtsklick auf den Link ausführen und die Funktion 'Ziel speichern unter' aus dem Menü verwenden" oder so ähnlich.
            So eine Antwort hätte ich von dir nicht erwartet :)

            Warum nicht? Ich bin für Aufklärung statt Bevormundung oder gar Nötigung. Bestes Beispiel ist, ungefragt neues Fenster/Tab öffnen, weil Anwender vielleicht die "Öffnen im neuen Fenster/Tab"-Option ihres Browsers nicht kennen.

            Man muss unwissenden Anwendern auch mal beibringen, wie etwas geht, anstatt ihnen selbst solch einen simplen Zweitklick abnehmen zu wollen.
            Ja, aber hier stehe ich eher auf der Seite, dass man das nicht auf der Website tun sollte.

            Wo dann?

            An einer Ampel steht ja auch kein Schild "Fahren sie bei grünem Licht" :)

            Das ist Allgemeinwissen, bekommt man im Kleinkindalter erklärt.

            Grundfunktionen eines Browsers im Frontend einer Website direkt zu erklären finde ich falsch. Irgendwo ein kleines Fragezeichen mit einem Tooltip oder einem Link zu einer Hilfe-Seite ist ok, aber direkt unter oder nebene einem Bild/Link/etc. finde ich äußerst fragwürdig.

            Nun, über die Art der Darstellung des Hinweises kann man sicher diskutieren. Dass er anscheinend überhaupt gegeben werden muss, ist wohl leider immer noch notwendig. Ansonsten würde wohl wie in diesem Fall nicht die Ansicht bestehen, dem Anwender eine seiner Browserfunktionen nachbilden zu müssen, weil er sie sonst nicht findet.

            Lo!

            1. Hi!

              "Zum Download bitte einen Rechtsklick auf den Link ausführen und die Funktion 'Ziel speichern unter' aus dem Menü verwenden" oder so ähnlich.
              So eine Antwort hätte ich von dir nicht erwartet :)

              Warum nicht? Ich bin für Aufklärung statt Bevormundung oder gar Nötigung.

              Wenn man das geringere Übel wählen muss, dann ja :)

              Bestes Beispiel ist, ungefragt neues Fenster/Tab öffnen, weil Anwender vielleicht die "Öffnen im neuen Fenster/Tab"-Option ihres Browsers nicht kennen.

              Sicher - aber schreibst du deshalb daneben hin, dass jemand mit Rechtsklick "Link in neuem Tab/Fenster öffnen" das selbst entscheiden kann (und respektive die Anleitung für die anderen 5 Browser und Betriebssystem auch gleich?

              Wo dann?

              In einem Kurs, den jeder machen sollte müssen bevor er das Internet verwendet - oder in der Schule.

              Das ist Allgemeinwissen, bekommt man im Kleinkindalter erklärt.

              Das ist die Bedienung "des Internets" heutzutage auch - so wie das Fahrradfahren.

              Nun, über die Art der Darstellung des Hinweises kann man sicher diskutieren. Dass er anscheinend überhaupt gegeben werden muss, ist wohl leider immer noch notwendig. Ansonsten würde wohl wie in diesem Fall nicht die Ansicht bestehen, dem Anwender eine seiner Browserfunktionen nachbilden zu müssen, weil er sie sonst nicht findet.

              Das habe ich nicht bestritten, drum sagte ich ja: ein kleines Fragezeichen mit Tooltip oder ähnlichem :)

              1. Hi!

                Bestes Beispiel ist, ungefragt neues Fenster/Tab öffnen, weil Anwender vielleicht die "Öffnen im neuen Fenster/Tab"-Option ihres Browsers nicht kennen.
                Sicher - aber schreibst du deshalb daneben hin, dass jemand mit Rechtsklick "Link in neuem Tab/Fenster öffnen" das selbst entscheiden kann (und respektive die Anleitung für die anderen 5 Browser und Betriebssystem auch gleich?

                Ja, nur nicht so ausführlich. Ein Verweis auf die Rechtsklickmöglichkeit finde ich genug. Die passende Funktion können sich die Anwender durch Lesen des Kontextmenüs raussuchen, so viel Intelligenz billige ich ihnen zu.

                Im SELFHTML-Wiki gibt es beim Seiteneditieren eine Syntax-Hinweis-Box, die einen Verweis zur ausführlichen Hilfe enthält. Dieser war zu Anfang mit einem target=_blank versehen, welches ich entfernt habe. Der Hinweis, der jetzt dafür steht, sollte/muss reichen.

                Lo!

      3. Hi,

        Der öffnet allerdings nicht zum Download.. example.com/test.html wird nicht zum Download geöffnet.

        zu was denn sonst? Das Übertragen der Daten vom entfernten auf den eigenen Rechner *ist* der Download. Was anschließend mit den Daten passiert, sagt dieser Begriff weder aus, noch schränkt er es ein. Die Darstellung im Browser und das umgehende Versenken der Daten im Mülleimer sind gleichermaßen davon abgedeckt.

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Hi!

          Der öffnet allerdings nicht zum Download.. example.com/test.html wird nicht zum Download geöffnet.
          zu was denn sonst?

          Nun sei mal nicht so pingelig, wenn es für den vorliegenden Fall keine gesteigerte Bedeutung hat. Es geht aus dem Kontext klar hervor, dass er "mit einfachem Klick zum Speichern angeboten" meinte.

          Lo!

          1. Hi,

            Der öffnet allerdings nicht zum Download.. example.com/test.html wird nicht zum Download geöffnet.
            zu was denn sonst?
            Nun sei mal nicht so pingelig, [...]

            was ist daran pingelig, jemandem etwas zu erklären, das zum Verständnis einer Antwort beiträgt, die er offenkundig nicht verstanden hat?

            Cheatah

            --
            X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
            X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
    2. Hi Vinzenz!

      Wenn ich es richtig sehe muss bei meiner Lösung erst mein Server die Datei holen um sie dann als download anbieten zu können. Kann ich erreichen, dass dem Client direkt die Datei als Download angeboten wird?

      ja selbstverständlich: das Verfahren dazu benötigt überhaupt keine Programmiersprache, das geht mit HTML der allerersten Stunde. Verwende einfach einen Link.

      Das von Dir? Da bin ich echt enttäuscht - das ist blanker Unsinn!

      Ein HTTP-Header "Content-disposition: attachment" könnte helfen, denn ich verstehe OP so, dass ein Download unbedingt gewünscht ist.

      off:PP

      --
      "You know that place between sleep and awake, the place where you can still remember dreaming?" (Tinkerbell)
      1. Ein HTTP-Header "Content-disposition: attachment" könnte helfen, denn ich verstehe OP so, dass ein Download unbedingt gewünscht ist.

        Und das "Content-Type: application/octet-stream" nicht vergessen - aber das hat der OP auch schon erwähnt.

        Aber dafür braucht man keine Programmiersprache, das kann man dem Webserver auch beibringen:
        http://httpd.apache.org/docs/2.2/mod/mod_headers.html#header

        1. Ja, ich sende ja die header, aber dann muss ich mit file_get_contents den Inhalt von der URL abrufen und ausgeben, d. h. doch, dass der Inhalt über meinen Server geschleust wird bis er beim Client landet?

          Und erst die beiden genannten header und dann ein Location-Header klappt ja nicht.

          1. Hallo,

            Ja, ich sende ja die header, aber dann muss ich mit file_get_contents den Inhalt von der URL abrufen und ausgeben

            selbstverständlich.

            d.h. doch, dass der Inhalt über meinen Server geschleust wird bis er beim Client landet?

            Selbstverständlich. Schließlich handelt es sich um *einen* Request. Oder meinst du, man könnte ein paar HTTP-Header senden, und den Client *dann* woanders hinschicken (Redirect), wo er die gewünschte Ressource erneut anfragen soll?
            Nein, wer gackert, muss auch legen. Hier: Wer HTTP-Header sendet, muss auch den Response Body dazu senden[*]; ein HTTP-Zyklus besteht aus Request und Response und wird zwsichen genau zwei Hosts abgewickelt. Ein Weiterschicken innerhalb dieses HTTP-Zyklus geht nicht.

            Und erst die beiden genannten header und dann ein Location-Header klappt ja nicht.

            Doch, sicher. Aber dann sind die Header Content-Type und Content-Disposition sinnlos, denn es gibt ja keinen Content, auf den sie sich beziehen könnten. Und das Anfordern der Ressource vom eigentlichen Zielserver ist dann wieder ein eigenständiger HTTP-Zyklus.

            So long,
             Martin

            [*] Ausnahme: Content-Length gibt 0 an, implizit z.B. bei HTTP-Status 204 oder 304.

            --
            Man sollte immer wissen was man sagt
             - aber auf keinen Fall alles sagen, was man weiß.
            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
          2. Hi!

            Ja, ich sende ja die header, aber dann muss ich mit file_get_contents den Inhalt von der URL abrufen und ausgeben, d. h. doch, dass der Inhalt über meinen Server geschleust wird bis er beim Client landet?

            Ich nehme mal an, dass du auf den Webserver, von dem der Anwender das Dokument eigentlich holen soll, keinen Einfluss nehmen kannst. Richtig? Denn nur dann könntest du die Header entsprechend den gegebenen Tipps direkt setzen.

            Und erst die beiden genannten header und dann ein Location-Header klappt ja nicht.

            Der Location-Header schickt den Browser des Anwenders zu einem neuen Ziel, das er mit einem neuen Request beglücken muss. Das Ziel kann er im Grunde genommen auch direkt aufrufen und benötigt auch für den Fall korrekte HTTP-Header. Also muss der Server eigene Header senden. Für den Request zu deinem Server kannst du HTTP-Header mitsenden, aber sie gelten eben nur für deinen Request und bei Weiterleitungsanworten nicht für den nächsten notwendigen Request. Sonst könnte ja jeder kommen, auf irgendwas verweisen und den Content-Type nach Gutdünken fälschen.

            Die einzige (mir bekannte) Möglichkeit, zu einem Verweis einen Content-Type bekanntzugeben ist das type-Attribut des a-Elements. Aber das hat in der Theorie nur hinweisenden Charakter für den Browser, dass er den Request gleich ganz sein lassen kann, wenn er den Content-Type nicht verarbeiten kann. Praktisch ist es vermutlich bedeutungslos. Es überschreibt jedoch auf keinen Fall die Pflicht-Angabe im HTTP-Header.

            Lo!

  2. hi,

    Wie kann ich das komfortabler/besser erreichen?

    mit einer zweckmäßigen Projektverwaltung.

    Wenn ich es richtig sehe muss bei meiner Lösung erst mein Server die Datei holen um sie dann als download anbieten zu können.

    Der Server muss das tun, ja. Der Server kann die Datei jedoch auch von einem Script bekommen damit er sie ausliefern kann.

    Kann ich erreichen, dass dem Client direkt die Datei als Download angeboten wird?

    Der Download-Dialog erscheint beim Besucher, wenn dem seine Konfiguration den vorangestellten Content-Type nicht kennt. Empfohlen dazu wird oft der Content-Type: application/octet-stream

    Wenn alles über ein Script läuft und eine griffige Projektverwaltung auch die Attribute zu jedem URL verwaltet, ist das hier möglich:

    [/download/IPv4.pm]
    title=IPv4 Calculate IPv4-Address and looking for Subnets
    descr=Download Perl-Modul zum Berechnen von IP-Adressen und Subnetzen
    isa=perlfile IPv4.pm
    type=text/plain

    Was daraus wird:

    • kennt der Browser text/plain, zeigt er die Datei. Beim Speichern unter... steht der Dateiname IPv4.pm im Dialog
    • kennt der Browser den Content-Type nicht oder wird gleich Speichern unter gewählt, steht ebenfalls der Dateiname IPv4.pm im Dialog.

    Hotti