(HTML) Laden Sie eine PDF-Datei herunter, anstatt sie beim Klicken im Browser zu öffnen


114

Ich habe mich gefragt, wie ich einen PDF-Dateilink zum Herunterladen machen kann, anstatt ihn im Browser zu öffnen. Wie geht das in HTML? (Ich würde annehmen, dass es über Javascript oder so gemacht wird).


3
Dies ist meines Wissens kein skriptfähiges Verhalten. Die meisten Browser haben ihre eigenen Einstellungen für das Verhalten bei bestimmten Dateitypen beim Herunterladen.
Bart

1
Ab HTML5 sollte das OP die richtige Antwort auf Sarims Antwort aktualisieren.
Omar Tariq

Mögliches Duplikat von Force zum Öffnen
Popups

Diese Frage wurde auch hier beantwortet: stackoverflow.com/a/30714824/847235
intrepidis

Antworten:


38

Mit HTML ist dies nicht möglich. Es ist eine serverbasierte Lösung. Sie müssen die Datei streamen, damit der Browser dann den Speicherdialog auslöst.

Ich würde raten, dies nicht zu tun. Wie ein Benutzer mit einer PDF-Datei interagiert, sollte dem Benutzer überlassen bleiben.

UPDATE (2014):

Also ... diese Antwort bekommt immer noch viele Downvotes. Ich gehe davon aus, dass dies vor 4 Jahren beantwortet wurde und wie Sarim betont, gibt es jetzt das HTML 5- downloadAttribut , das damit umgehen kann.

Ich stimme zu und denke, dass Sarims Antwort gut ist (es sollte wahrscheinlich die gewählte Antwort sein, wenn das OP jemals zurückkehrt). Diese Antwort ist jedoch immer noch die zuverlässige Methode, um damit umzugehen (wie die Antwort von Yiğit Yener hervorhebt und - seltsamerweise - die Leute zustimmen). Obwohl das Download-Attribut Unterstützung erhalten hat, ist es immer noch fleckig:

http://caniuse.com/#feat=download


18
Ich weiß, dass dies ein Jahr alt ist - aber ich bin anderer Meinung. Unter bestimmten Umständen ist das Erzwingen dieses Verhaltens für den Anwendungsfluss sehr wichtig. Die eigentliche Antwort besteht darin, die Inhaltsdisposition in der Kopfzeile auf "Anhang" anstatt auf "Inline" zu setzen.
user158017

9
Ich bin damit einverstanden, dass es unter anderen Umständen besser ist, es der Benutzerkontrolle zu überlassen. Ich bin jedoch zu diesem Thread gekommen, um nach einer Antwort zu suchen, und die aktivierte "Antwort" war keine Antwort - es war "Sie sollten das nicht tun". Für mich ist das keine Antwort auf die Frage. Geben Sie stattdessen eine spezifische Antwort und auch beraten.
user158017

1
Manchmal ist die Frage falsch. ;) Wie auch immer, in Bezug auf dein Problem ist das alles ein UX-Problem. Manchmal ist es notwendig, das Web zu einem bestimmten Verhalten zu zwingen, aber aus UX-Sicht gibt es oft bessere Lösungen. Auch meine Antwort ist richtig. Sie können mit HTML nicht das tun, was Sie wollen (was die Frage stellte). Es ist als serverseitige Lösung.
DA.

1
Dies ist eine meiner seltsamsten Antworten, die jemals veröffentlicht wurden. Die Leute finden immer noch ihren Weg hierher, um es abzustimmen. Welches ist in Ordnung! Aber es wäre interessant zu wissen warum.
DA.

3
Über diese Herabstimmung mag es der Untergang der Zivilisation sein, wie leicht es ist, im Text ungewollt arrogant zu wirken. Diese Antwort fällt mir so lange auf, wie ich die Meinung bevormunden und wie kurz die Antworten sind. Fügen Sie anstelle von Absatz 1 einfach das httpTag zur Frage hinzu. Anstelle von Absatz 2: "Vielleicht möchten Sie noch einmal überlegen, ob das Verhindern einer sofortigen PDF-Anzeige im besten Interesse aller Benutzer liegt. Allerdings ..." Nehmen Sie dann an, dass das OP und zukünftige Leser Erwachsene sind, und fahren Sie mit einer umsetzbaren Antwort wie der von Yener fort .
Bob Stein

133

Mit HTML5 ist das jetzt möglich. Stellen Sie ein "Download" -Attr im Element ein.

<a href="http://link/to/file" download="FileName">Download it!</a>

Quelle: http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download


Sie sollten sich besser für diese Lösung entscheiden, wenn sie unterstützt wird. Hier ist eine Möglichkeit zu überprüfen, ob es istif ("download" in document.createElement("a")){ ... }
pmrotule

Ich habe unten eine weitere Antwort hinzugefügt (allerdings schlechter Hack), obwohl dies immer noch der bevorzugte Weg ist, könnte der Hack-Weg vielleicht für nicht unterstützte Browser angeboten werden.
Sarim

Gibt es eine Möglichkeit, den Text für das PDF anzugeben, anstatt den Dateipfad zu erwähnen? Ich muss PDF aus einem Div-HTML erstellen, aber ich möchte kein weiteres Fenster öffnen. Der Download sollte so aussehen wie in dieser Antwort.
T.Adak

1
Wie im August 2019 scheint die Browser-Unterstützung für diese Funktion verbessert zu sein, siehe: w3schools.com/tags/att_a_download.asp
Daniel Resch

2
Beachten Sie, dass das Download-Attribut nur für Anforderungen mit demselben Ursprung unterstützt wird.
Quentin

82

Dies ist nur möglich, wenn ein http-Antwortheader durch den serverseitigen Code festgelegt wird. Nämlich;

Content-Disposition: attachment; filename=fname.ext

2
Dies ist die perfekte Antwort - finden Sie einfach den Weg, dies in der entsprechenden serverseitigen Sprache zu tun.
user158017


Leider zeigt iOS weiterhin eine Vorschau an und lädt keine PDF-Dateien herunter, selbst wenn die Inhaltsdisposition "Anhang" ist.
Jorn van de Beek

14

Sie müssen die gesendeten http-Header ändern. Abhängig von Ihrem Server können Sie Ihren .htaccess wie folgt ändern:

<FilesMatch "\.(?i:pdf)$">
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</FilesMatch>

Über den Inhaltstyp muss nicht gelogen werden. Das Einstellen der Inhaltsdisposition ist ausreichend.
Quentin

9

Sie müssen ein PHP-Skript (oder eine andere serverseitige Sprache dafür) verwenden.

<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');

// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf
readfile('original.pdf');
?>

und verwenden Sie httacces, um zur PHP-Datei anstatt zum PDF umzuleiten (umzuschreiben)


Hmm, es funktioniert super, wenn ich die PHP-Datei direkt öffne. Wenn ich jedoch versuche, die Umleitung wie hier zu verwenden: Redirect 301 /_PDFs/Catalogue.pdf http://www.example.com/_PDFs/___download_the_catalogue_instead_opening.phpund versuche, die PDF-Datei zu öffnen, wird das Original weiterhin im Browser geöffnet, stattdessen wird die umbenannte Version heruntergeladen ...
ellockie

UPDATE: Es funktioniert, wenn keine Datei direkt aufgerufen wird (in meinem Beispiel als "Catalogue.pdf"). Dann funktioniert die Umleitung einwandfrei. Vielen Dank!
Ellockie

8

Sie können verwenden

Response.AddHeader("Content-disposition", "attachment; filename=" + Name);

Schauen Sie sich dieses Beispiel an:

http://www.codeproject.com/KB/aspnet/textfile.aspx

Dies gilt für ASP.NET. Ich bin sicher, dass Sie ähnliche Lösungen in allen anderen serverseitigen Sprachen finden können. Nach meinem besten Wissen gibt es jedoch keine Javascript-Lösung.


Dies ist die Antwort (sowie die zugehörige für PHP). Der Punkt ist, dass der http-Antwortheader bearbeitet werden muss.
user158017

5

Ohne das HTML5-Attribut kann man dies mit php erreichen:

Erstellen Sie eine PHP-Datei mit dem Namen download.php mit diesem Code:

<?php
ob_start();
$file = "yourPDF.pdf"

if (file_exists($file)) 
{
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit();
}

Wenn Sie nun automatisch mit dem Herunterladen von PDF-Dateien beginnen möchten, schreiben Sie dieses Javascript:

<script>window.location = "download.php";</script>

Wenn dies für einen Link funktionieren soll, verwenden Sie diesen ...

<a href='javascript:window.location = "download.php"'>
    Download it!
</a>

4
Nur ein Hinweis, dass Sie vorsichtig sein müssen, wenn Sie dies mit URL-Parametern tun. Zum Beispiel $file = $_GET['$file'];. Denn man könnte dann auch download.php?file=../../../wp-config.phpeine andere gegebene Ressource aufrufen . Zusätzliche Überprüfung auf Erweiterungen, MIME-Typen und zulässige Pfade zum Herunterladen (und Entfernen von Dingen wie "../") ist sehr wichtig!
Giel Berkers

bin ich es oder mache <a href='javascript...'> genau das gleiche wie das direkte <a href='download.php'> ?
Einfügen

5

Wenn Sie ein Bild oder eine PDF-Datei direkt vom Browser herunterladen möchten, anstatt sie in einem neuen Tab zu öffnen, sollten Sie in Javascript den Wert für das Download-Attribut zum Erstellen eines dynamischen Links festlegen

    var path= "your file path will be here"; 
    var save = document.createElement('a');  
    save.href = filePath; 
    save.download = "Your file name here"; 
    save.target = '_blank'; 
    var event = document.createEvent('Event');
    event.initEvent('click', true, true); 
    save.dispatchEvent(event);
   (window.URL || window.webkitURL).revokeObjectURL(save.href);

Bei einem neuen Chrome-Update funktioniert ein Zeitereignis nicht. Für diesen wird der folgende Code verwendet

  var path= "your file path will be here"; 
    var save = document.createElement('a');  
    save.href = filePath; 
    save.download = "Your file name here"; 
    save.target = '_blank'; 
    document.body.appendChild(save);
    save.click();
    document.body.removeChild(save);

Das Anhängen eines Kindes und das Entfernen eines Kindes ist nur für Firefox, den Internet Explorer-Browser, nützlich. Auf Chrome funktioniert es, ohne dass ein Kind angehängt und entfernt wird


2

Die Lösung, die für mich am besten funktioniert hat, war die, die Nick in seinem Blog geschrieben hat

Die Grundidee seiner Lösung besteht darin, den Header-Mod des Apache-Servers zu verwenden und den .htaccess so zu bearbeiten, dass er eine FileMatch-Direktive enthält, die alle * .pdf-Dateien dazu zwingt, anstelle eines Anhangs als Stream zu fungieren. Dies beinhaltet zwar nicht das Bearbeiten von HTML (gemäß der ursprünglichen Frage), erfordert jedoch keine Programmierung an sich.

Der erste Grund, warum ich Nicks Ansatz vorgezogen habe, ist, dass ich ihn auf Ordnerbasis festlegen konnte, sodass PDF-Dateien in einem Ordner weiterhin im Browser geöffnet werden können, während andere zugelassen werden (diejenigen, die Benutzer bearbeiten und dann erneut hochladen sollen). als Downloads gezwungen werden.

Ich möchte auch hinzufügen, dass es bei PDFs eine Option gibt, ausfüllbare Formulare über eine API an Ihre Server zu senden / zu senden, aber die Implementierung dauert eine Weile.

Der zweite Grund war, dass Zeit eine Überlegung ist. Das Schreiben eines PHP-Datei-Handlers, um die Inhaltsdisposition im Header () zu erzwingen, dauert ebenfalls weniger Zeit als eine API, aber immer noch länger als Nicks Ansatz.

Wenn Sie wissen, wie man einen Apache-Mod einschaltet und die .htaccss bearbeitet, können Sie dies in etwa 10 Minuten erhalten. Es erfordert Linux-Hosting (nicht Windows). Dies ist möglicherweise nicht für alle Verwendungszwecke geeignet, da für die Konfiguration ein Serverzugriff auf hoher Ebene erforderlich ist. Wenn Sie also Zugriff gesagt haben, liegt dies wahrscheinlich daran, dass Sie bereits wissen, wie diese beiden Dinge zu tun sind. Wenn nicht, überprüfen Sie Nicks Blog für weitere Anweisungen.


2

Da der HTML5-Weg (meine vorherige Antwort) nicht in allen Browsern verfügbar ist, ist hier ein weiterer leicht hackiger Weg.

Für diese Lösung müssen Sie die beabsichtigte Datei aus derselben Domäne bereitstellen, ODER Sie haben die CORS-Berechtigung.

  1. Laden Sie zuerst den Inhalt der Datei über XMLHttpRequest (Ajax) herunter.
  2. Erstellen Sie dann einen Daten-URI, indem Sie base64 den Inhalt der Datei codieren und den Medientyp auf festlegen application/octet-stream. Ergebnis sollte so aussehen

data:application/octet-stream;base64,SGVsbG8sIFdvcmxkIQ%3D%3D

Jetzt einstellen location.href = data. Dadurch lädt der Browser die Datei herunter. Leider können Sie den Dateinamen oder die Erweiterung nicht auf diese Weise festlegen. Das Fummeln mit dem Medientyp könnte etwas bringen.

Siehe Details: https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs



1

Wenn Sie HTML5 verwenden (und ich denke, dass heutzutage jeder das verwendet), gibt es ein Attribut namens download.

Ex. <a href="somepathto.pdf" download="filename">

Hier filenameist optional, aber falls angegeben, wird dieser Name für die heruntergeladene Datei verwendet.


Leider muss ich zugeben, dass ich zu dumm bin, um diesen Tag zu verstehen. Ich sage dies: <a href="download/Curriculum_it.pdf.zip">Download curriculum</a>oder das: <a href="download/Curriculum_it.pdf.zip" download="Curriculum_it">Download curriculum</a>und ich kann absolut keinen Unterschied darin sehen, wie es funktioniert. Beide laden meine .zip herunter. Und im zweiten Fall scheint die Verwendung der Dateinamenoption überhaupt nichts zu bewirken.
Garavani

0

Das Verhalten sollte davon abhängen, wie der Browser für die Verarbeitung verschiedener MIME-Typen eingerichtet ist. In diesem Fall lautet der MIME-Typ application / pdf. Wenn Sie den Browser zum Herunterladen der Datei zwingen möchten, können Sie versuchen, einen anderen MIME-Typ für die PDF-Dateien zu erzwingen. Ich empfehle dagegen, da der Benutzer selbst entscheiden sollte, was beim Öffnen einer PDF-Datei passieren soll.


0

Sie können download.js verwenden ( https://github.com/rndme/download und http://danml.com/download.html ). Wenn sich die Datei in einer externen URL befindet, müssen Sie eine Ajax-Anfrage stellen. Ist dies nicht der Fall, können Sie die folgende Funktion verwenden:

download(Path, name, mime)

Lesen Sie die Dokumentation für weitere Details im GitHub.


Dies ist die beste Javascript-Lösung für Downloads in einer anderen Domain.
Edhowler

-1

Endlich habe ich gefunden ...... dynamisches Ankertag erstellen und darauf klicken

<script> 
   $('#myclick').click(function(){
       $('body').append('<a id="link" href="mypdf.pdf" 
        download="Payment.pdf">&nbsp;</a>');
       $('#link')[0].click();
   });
</script>

'Payment.pdf' ist nur für benutzerdefinierte Namen.


Der Link muss nicht dynamisch generiert werden.
Quentin

Beachten Sie, dass das Download-Attribut nur für Anforderungen mit demselben Ursprung unterstützt wird.
Quentin

Dies scheint die gleiche Antwort zu sein wie diese aus drei Jahren zuvor.
Quentin
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.