(HTML) Unduh file PDF alih-alih membukanya di browser saat diklik

115

Saya bertanya-tanya bagaimana cara membuat tautan file PDF dapat diunduh alih-alih membukanya di browser? Bagaimana ini dilakukan di html? (Saya akan berasumsi itu dilakukan melalui javascript atau sesuatu).

404Error
sumber
3
Ini sepengetahuan saya, bukan perilaku yang dapat dituliskan. Sebagian besar browser akan memiliki pengaturannya sendiri untuk perilaku apa yang harus dilakukan dengan jenis file tertentu saat diunduh.
Bart
1
Pada HTML5, OP harus mengupdate jawaban yang benar untuk jawaban Sarim.
Omar Tariq
kemungkinan duplikat Force to open "Save As ..." popup terbuka di tautan teks klik untuk pdf dalam HTML
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Pertanyaan ini juga telah dijawab di sini: stackoverflow.com/a/30714824/847235
intrepidis

Jawaban:

38

Anda tidak dapat melakukan ini dengan HTML. Ini adalah solusi berbasis server. Anda harus melakukan streaming file agar browser memicu dialog simpan.

Saya menyarankan untuk tidak melakukan ini. Bagaimana pengguna berinteraksi dengan PDF harus diserahkan kepada pengguna.

UPDATE (2014):

Jadi ... jawaban ini masih banyak mendapat downvote. Saya berasumsi sebagian dari itu adalah bahwa ini telah dijawab 4 tahun yang lalu dan seperti yang Sarim tunjukkan, sekarang ada atribut HTML 5download yang dapat menangani ini.

Saya setuju, dan menurut saya jawaban Sarim bagus (mungkin itu jawaban yang dipilih jika OP pernah kembali). Namun, jawaban ini masih merupakan cara yang dapat diandalkan untuk menanganinya (seperti yang ditunjukkan oleh jawaban Yiğit Yener dan - anehnya - orang setuju dengannya). Meskipun atribut download telah mendapatkan dukungan, itu masih belum tentu:

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

DA.
sumber
18
Saya tahu ini berumur satu tahun - tapi saya tidak setuju. Ada keadaan di mana memaksa perilaku ini sangat penting untuk alur aplikasi. Jawaban sebenarnya adalah menyetel Disposisi konten di tajuk menjadi "lampiran", bukan "sebaris".
pengguna158017
9
Saya setuju bahwa dalam keadaan lain, lebih baik menyerahkannya kepada kontrol pengguna. Namun, saya datang ke utas ini untuk mencari jawaban, dan "jawaban 'yang dicentang bukanlah jawaban - itu adalah" Anda tidak boleh melakukan itu. "Bagi saya, itu bukan jawaban untuk pertanyaan. Sebaliknya, berikan jawaban spesifik dan juga saran.
user158017
1
Terkadang pertanyaannya salah. ;) Bagaimanapun, tentang masalah Anda, itu semua adalah masalah UX. Terkadang perlu memaksa web untuk berperilaku dengan cara tertentu, tetapi seringkali ada solusi yang lebih baik dari perspektif UX. Juga, jawaban saya benar. Anda tidak dapat melakukan apa yang ingin Anda lakukan dengan HTML (seperti pertanyaan yang diajukan). Ini sebagai solusi sisi server.
DA.
1
Ini adalah salah satu jawaban teraneh saya yang pernah diposting. Orang-orang masih mencari cara untuk tidak menyukainya. Mana yang bagus! Tapi akan menarik untuk mengetahui alasannya.
DA.
3
Tentang downvoting itu, mungkin saja kehancuran peradaban betapa mudahnya terlihat arogan secara tidak sengaja dalam teks. Jawaban ini mengejutkan saya selama menggurui opini dan kekurangan jawaban. Sebagai ganti paragraf 1, tambahkan saja httptag ke pertanyaan. Alih-alih paragraf 2: "Anda mungkin ingin mempertimbangkan kembali apakah mencegah langsung melihat PDF adalah untuk kepentingan terbaik semua pengguna. Karena itu ..." Kemudian asumsikan OP dan pembaca mendatang adalah orang dewasa dan lanjutkan ke jawaban yang dapat ditindaklanjuti seperti Yener's .
Bob Stein
133

Dengan html5, sekarang dimungkinkan. Setel elemen "unduh".

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

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

Sarim
sumber
Anda lebih baik menggunakan solusi ini jika didukung. Berikut cara untuk memeriksa apakah ituif ("download" in document.createElement("a")){ ... }
pmrotule
saya menambahkan jawaban lain di bawah ini (meskipun peretasan buruk), sementara ini masih merupakan cara yang disukai, mungkin cara peretasan dapat ditawarkan untuk peramban yang tidak didukung.
Sarim
Apakah ada cara agar seseorang dapat menentukan teks untuk pdf daripada menyebutkan jalur file? Saya perlu membuat pdf dari div html tetapi saya tidak ingin membuka jendela lain, unduhan seharusnya tidak terlihat seperti dalam jawaban ini ..
T. Adak
1
Seperti sekarang Agustus 2019, dukungan Browser tampaknya ditingkatkan untuk fitur ini, lihat: w3schools.com/tags/att_a_download.asp
Daniel Resch
2
Perhatikan bahwa atribut download hanya didukung untuk permintaan yang sama asal.
Quentin
82

Ini hanya dapat dilakukan dengan menyetel header tanggapan http dengan kode sisi server. Yaitu;

Content-Disposition: attachment; filename=fname.ext
Yiğit Yener
sumber
2
ini adalah jawaban yang tepat - temukan saja cara melakukannya dalam bahasa sisi server yang sesuai.
pengguna158017
Contoh Apache . Contoh Flask .
Bob Stein
Sayangnya iOS masih akan mempratinjau dan tidak mengunduh file pdf meskipun disposisi kontennya adalah 'lampiran'.
Jorn van de Beek
14

Anda perlu mengubah header http yang dikirim. Bergantung pada server Anda, Anda dapat mengubah .htaccess Anda sebagai berikut:

<FilesMatch "\.(?i:pdf)$">
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</FilesMatch>
php guy
sumber
Tidak perlu berbohong tentang jenis konten. Mengatur disposisi konten sudah cukup.
Quentin
9

Anda perlu menggunakan skrip PHP (atau bahasa sisi server lain untuk ini)

<?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');
?>

dan gunakan httacces untuk mengarahkan (menulis ulang) ke file PHP, bukan pdf

kode jenggot
sumber
Hmm, ini berfungsi dengan baik ketika saya membuka file php secara langsung. Tetapi ketika saya mencoba menggunakan pengalihan, seperti di sini: Redirect 301 /_PDFs/Catalogue.pdf http://www.example.com/_PDFs/___download_the_catalogue_instead_opening.phpdan mencoba membuka file pdf, itu masih membuka yang asli di browser, alih-alih mengunduh versi yang diganti namanya ...
ellockie
UPDATE: Ini berfungsi ketika tidak ada file yang secara langsung dipanggil (sebagai "Catalogue.pdf" dalam contoh saya). Kemudian pengalihan bekerja dengan sempurna. Terima kasih!
ellockie
8

Kamu bisa memakai

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

Lihat contoh ini:

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

Ini berlaku untuk ASP.NET. Saya yakin Anda dapat menemukan solusi serupa di semua bahasa sisi server lainnya. Namun tidak ada solusi javascript yang terbaik dari pengetahuan saya.

mihsathe
sumber
ini adalah jawabannya (serta yang terkait untuk PHP). intinya adalah bahwa header tanggapan http harus diedit.
pengguna158017
5

Tanpa atribut html5 seseorang dapat mencapai ini dengan menggunakan php:

Buat file php bernama download.php dengan kode ini:

<?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();
}

Sekarang jika Anda ingin mengunduh pdf secara otomatis, tulis javascript ini:

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

Jika Anda ingin ini berfungsi pada tautan, gunakan ini ...

<a href='javascript:window.location = "download.php"'>
    Download it!
</a>
hlozancic
sumber
4
Perlu diketahui bahwa Anda perlu berhati-hati saat akan melakukan ini dengan parameter URL. Misalnya $file = $_GET['$file'];. Karena seseorang juga dapat memanggil download.php?file=../../../wp-config.phpatau sumber daya lain yang diberikan. Pemeriksaan tambahan untuk ekstensi, jenis pantomim dan jalur yang diizinkan untuk mengunduh (dan menghapus hal-hal seperti "../") sangat penting!
Giel Berkers
apakah ini saya atau melakukan <a href='javascript...'> sama persis dengan memasukkan tautan secara langsung<a href='download.php'> ?
allan.simon
5

Ketika Anda ingin langsung mengunduh gambar atau file pdf dari browser alih-alih membukanya di tab baru maka di javascript Anda harus mengatur nilai untuk mengunduh atribut buat tautan dinamis

    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);

Untuk pembaruan Chrome baru beberapa acara waktu tidak berfungsi. untuk kode berikut akan digunakan

  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);

Menambahkan anak dan menghapus anak berguna untuk Firefox, browser penjelajah Internet saja. Di chrome ini akan bekerja tanpa menambahkan dan menghapus child

Prasad Joshi
sumber
2

Solusi yang paling berhasil untuk saya adalah yang ditulis oleh Nick di blognya

Ide dasar dari solusinya adalah dengan menggunakan mod header server Apache dan mengedit .htaccess untuk menyertakan direktif FileMatch yang memaksa semua file * .pdf untuk bertindak sebagai aliran alih-alih lampiran. Meskipun ini tidak benar-benar melibatkan pengeditan HTML (sesuai pertanyaan asli), ini tidak memerlukan pemrograman apa pun.

Alasan pertama saya lebih suka pendekatan Nick adalah karena ini memungkinkan saya untuk mengaturnya berdasarkan per folder sehingga PDF dalam satu folder masih dapat dibuka di browser sambil mengizinkan orang lain (yang kami ingin pengguna mengedit dan kemudian mengunggahnya kembali) untuk dipaksa sebagai unduhan.

Saya juga ingin menambahkan bahwa ada opsi dengan PDF untuk mengirim / mengirimkan formulir yang dapat diisi melalui API ke server Anda, tetapi itu membutuhkan waktu untuk diterapkan.

Alasan kedua karena waktu adalah pertimbangan. Menulis penangan file PHP untuk memaksa disposisi konten di header () juga akan memakan waktu lebih sedikit daripada API, tetapi masih lebih lama daripada pendekatan Nick.

Jika Anda tahu cara mengaktifkan mod Apache dan mengedit .htaccss, Anda bisa mendapatkannya dalam waktu sekitar 10 menit. Ini membutuhkan hosting Linux (bukan Windows). Ini mungkin bukan pendekatan yang tepat untuk semua penggunaan karena memerlukan akses server tingkat tinggi untuk mengonfigurasi. Dengan demikian, jika Anda mengatakan akses, itu mungkin karena Anda sudah tahu cara melakukan dua hal itu. Jika tidak, periksa blog Nick untuk instruksi lebih lanjut.

Strixy
sumber
2

Karena cara html5 (jawaban saya sebelumnya) tidak tersedia di semua browser, berikut cara lain yang sedikit diretas.

Solusi ini mengharuskan Anda menyajikan file yang dimaksudkan dari domain yang sama, ATAU memiliki izin CORS.

  1. Pertama unduh konten file melalui XMLHttpRequest (Ajax).
  2. Kemudian buat URI data dengan base64 yang menyandikan konten file dan setel jenis media ke application/octet-stream. Hasilnya akan terlihat seperti ini

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

Sekarang siap location.href = data . Ini akan menyebabkan browser mengunduh file. Sayangnya Anda tidak dapat mengatur nama file atau ekstensi dengan cara ini. Mengotak-atik jenis media bisa menghasilkan sesuatu.

Lihat detailnya: https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs

Sarim
sumber
1

Jika Anda menggunakan HTML5 (dan saya rasa sekarang hari semua orang menggunakan itu), ada atribut yang disebut download.

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

di sini filenameopsional, tetapi jika disediakan, ini akan menggunakan nama ini untuk file yang diunduh.

Akshay
sumber
Sayangnya, saya harus mengakui bahwa saya terlalu bodoh untuk memahami tag ini. Saya mengatakan ini: <a href="download/Curriculum_it.pdf.zip">Download curriculum</a>atau itu: <a href="download/Curriculum_it.pdf.zip" download="Curriculum_it">Download curriculum</a>dan saya sama sekali tidak melihat perbedaan dalam cara kerjanya. Keduanya mengunduh .zip saya. Dan yang kedua menggunakan opsi nama file tampaknya tidak melakukan apa-apa.
Garavani
0

Perilaku tersebut harus bergantung pada cara browser disiapkan untuk menangani berbagai jenis MIME. Dalam hal ini tipe MIME adalah application / pdf. Jika Anda ingin memaksa browser untuk mengunduh file, Anda dapat mencoba memaksa jenis MIME yang berbeda pada file PDF. Saya merekomendasikan untuk tidak melakukannya karena seharusnya menjadi pilihan pengguna apa yang akan terjadi ketika mereka membuka file PDF.

Aleksi Yrttiaho
sumber
0

Anda dapat menggunakan download.js ( https://github.com/rndme/download dan http://danml.com/download.html ). Jika file ada di URL eksternal, Anda harus membuat permintaan Ajax, tetapi jika tidak, maka Anda dapat menggunakan fungsi:

download(Path, name, mime)

Baca dokumentasi mereka untuk detail lebih lanjut di GitHub.

Wisnu S.
sumber
Ini adalah solusi javascript terbaik untuk mengunduh di domain lain.
Edhowler
-1

Akhirnya saya menemukan ...... buat tag anchor dinamis dan klik di atasnya

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

'Payment.pdf' hanya untuk nama kustom.

Pushpender Singh
sumber
Tidak perlu membuat tautan secara dinamis.
Quentin
Perhatikan bahwa atribut download hanya didukung untuk permintaan yang sama asal.
Quentin
Ini sepertinya jawaban yang sama dengan yang ini dari tiga tahun sebelumnya.
Quentin