(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).

404 Fehler
quelle
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

DA.
quelle
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

Sarim
quelle
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
Yiğit Yener
quelle
2
Dies ist die perfekte Antwort - finden Sie einfach den Weg, dies in der entsprechenden serverseitigen Sprache zu tun.
user158017
Apache Beispiel. Kolbenbeispiel .
Bob Stein
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>
PHP-Typ
quelle
Ü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)

Bartcode
quelle
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.

mihsathe
quelle
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>
hlozancic
quelle
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

Prasad Joshi
quelle
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.

Strixy
quelle
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

Sarim
quelle
1

Ich musste dies für Dateien tun, die mit dynamischen Namen in einem bestimmten Ordner erstellt und von IIS bereitgestellt wurden.

Das hat bei mir funktioniert:

  • Wechseln Sie in IIS zu diesem Ordner und doppelklicken Sie auf HTTP-Antwortheader.
  • Fügen Sie einen neuen Header mit den folgenden Informationen hinzu:

    Name: content-disposition Value: attachment

(von: http://forums.iis.net/t/1175103.aspx?add+CustomHeaders+only+for+certain+file+types+ )

EricL
quelle
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.

Akshay
quelle
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.

Aleksi Yrttiaho
quelle
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.

Vishnu S.
quelle
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.

Pushpender Singh
quelle
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