HTML लिंक में पीडीएफ फाइल को डाउनलोड करने योग्य कैसे बनाएं?


124

मैं अपने वेब पेज पर पीडीएफ फाइल का लिंक नीचे की तरह डाउनलोड के लिए दे रहा हूं

<a href="myfile.pdf">Download Brochure</a>

समस्या तब है जब उपयोगकर्ता इस लिंक पर क्लिक करता है

  • यदि उपयोगकर्ता ने एडोब एक्रोबेट स्थापित किया है, तो यह एडोब रीडर में एक ही ब्राउज़र विंडो में फ़ाइल खोलता है।
  • यदि एडोब एक्रोबैट स्थापित नहीं है, तो यह फ़ाइल को डाउनलोड करने के लिए उपयोगकर्ता को पॉप-अप करता है।

लेकिन मैं चाहता हूं कि यह हमेशा डाउनलोड के लिए उपयोगकर्ता के लिए पॉप-अप हो, भले ही "एडोब एक्रोबैट" स्थापित हो या न हो।

कृपया मुझे बताएं कि मैं यह कैसे कर सकता हूं?

जवाबों:


116

इसके बजाय .PDF फ़ाइल से लिंक करने के बजाय, कुछ ऐसा करें

<a href="pdf_server.php?file=pdffilename">Download my eBook</a>

जो एक कस्टम हेडर को आउटपुट करता है, पीडीएफ खोलता है (बाइनरी सेफ़) और डेटा को उपयोगकर्ता के ब्राउज़र में प्रिंट करता है, फिर वे अपनी ब्राउज़र सेटिंग्स के बावजूद पीडीएफ को बचाने के लिए चुन सकते हैं। Pdf_server.php को इस तरह दिखना चाहिए:

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename=" . urlencode($file));   
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp); 

पुनश्च: और स्पष्ट रूप से "फ़ाइल" वैरिएबल पर कुछ चैनिटी चैन चलाएं ताकि लोग आपकी फाइलों को चोरी करने से रोक सकें जैसे कि फाइल एक्सटेंशन स्वीकार नहीं करते हैं, स्लैश से इनकार करते हैं, मूल्य में .pdf जोड़ें।


2
मुझे इसके साथ एक और समस्या का सामना करना पड़ रहा है, कि मेरी फ़ाइल /products/brochure/myfile.pdf पर स्थित है, मैं $ file चर को $ file_path = $ _SERVER ['DOCUMENT_ROOT]]] /' उत्पादों / विवरणिका / 'के रूप में दे रहा हूँ। फ़ाइल $; लेकिन इसकी फ़ाइल को "% 2Fvar% 2Fwww% 2Fweb15% 2Fweb% 2Fprobs% 2Fbrochure% 2myfile.pdf" के रूप में डाउनलोड करना
प्रशांत

3
@TravisO "Content-type: application/force-download"यहां कहीं भी सूचीबद्ध नहीं है: iana.org/assignments/media-types/application यह पूरी तरह से फर्जी हेडर है। कृपया हेडर न बनाएं और उन्हें भेजें। क्या आप अपना उत्तर अपडेट कर सकते हैं धन्यवाद।
निकोलस विल्सन

4
हालांकि इस कोड वर्बेटिम का उपयोग करते समय सावधान रहें। यह एक गंभीर LFI भेद्यता का परिचय देता है, जैसा कि आप सीधे GET- चर में पास कर रहे हैं fopen
जोस्ट

4
यह कोड दूसरी तरह से खतरनाक है। यदि आप fopen के लिए HTTP लिंक पास करते हैं, तो मुझे लगता है कि यह किसी अन्य सर्वर से फ़ाइल को पुनः प्राप्त करेगा। एक हमलावर द्वारा इस्तेमाल किया जा सकता है उजागर पीडीएफ फाइलों के लिए अपने आंतरिक नेटवर्क को स्कैन करने का प्रयास करें।
रोरी मैककेन

2
यह उल्लेख करना आसान नहीं है कि आपके द्वारा "फ़ाइल" पैरामीटर पर किए जा रहे किसी भी "पवित्रता चेक" को बायपास करना कितना आसान होगा। पथ इंजेक्शन / डायरेक्टरी ट्रैवर्सल अटैक की बेहद संभावना है।
AviD

209

यह एक सामान्य मुद्दा है, लेकिन कम ही लोग जानते हैं कि एक सरल HTML 5 समाधान है:

<a href="./directory/yourfile.pdf" download="newfilename">Download the pdf</a>

newfilenameफ़ाइल को सहेजने के लिए उपयोगकर्ता के लिए सुझाया गया फ़ाइल नाम कहाँ है। या यदि आप इसे खाली छोड़ते हैं, तो यह सर्वराइड पर फ़ाइल नाम के लिए डिफ़ॉल्ट होगा:

<a href="./directory/yourfile.pdf" download>Download the pdf</a>

संगतता: मैंने फ़ायरफ़ॉक्स 21 और आयरन पर इसका परीक्षण किया, दोनों ने ठीक काम किया। यह HTML5- असंगत या पुराने ब्राउज़रों पर काम नहीं कर सकता है। एकमात्र ऐसा ब्राउज़र जो मैंने परीक्षण किया था कि डाउनलोड करने के लिए बाध्य नहीं किया गया है IE ...

यहां संगतता की जांच करें: http://caniuse.com/#feat=download


9
यह एक सरल समाधान है लेकिन दुर्भाग्य से बहुत व्यापक रूप से समर्थित नहीं है, जासूसी। IE caniuse.com/#feat=download
benebun

2
हां, मैं सही जानता हूं। यही कारण है कि मेरे पास संगतता पर साइड-नोट है। और आपके स्रोत के अनुसार IE और सफारी दोनों इस दृष्टिकोण का समर्थन नहीं करते हैं, या कम से कम अभी तक नहीं :) किसी भी तरह, यदि आप सभी ब्राउज़रों को डाउनलोड करने के लिए मजबूर करना चाहते हैं तो मैं इसके बजाय कुछ अन्य उत्तरों की जांच करने का सुझाव देता हूं ...
T_D

3
क्रोम संस्करण 39.0.2171.65 (64-बिट) के साथ एक आकर्षण की तरह काम करता है!
edelans

समाधान आसान है लेकिन दुर्भाग्य से IE और सफारी में समर्थित नहीं है।
Valkirilov

का उपयोग करने की अनुमति नहीं
Hackbal Teamz

50

हर फ़ाइल लाइन के माध्यम से लूप न करें । इसके बजाए, रीडफाइल का उपयोग करें । यह php साइट बंद है: http://php.net/manual/en/function.readfile.php

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

किसी को कुछ php फ़ाइलों को डाउनलोड करने के रूप में अपने परिवर्तनशील चर को सुनिश्चित करें ...


4
Readfile समारोह वास्तव में तेजी से होता है। मैं व्यक्तिगत रूप से स्वीकार किए गए एक के बजाय इस उत्तर का उपयोग करने की सलाह देता हूं
जोस गारिडो 21

24

फ़ाइल को पढ़ने और फ्लश करने के लिए PHP स्क्रिप्ट का उपयोग करने के बजाय, हेडर का उपयोग करके इसे फिर से लिखना अधिक साफ है .htaccess। यह एक "अच्छा" URL (के myfile.pdfबजाय download.php?myfile) रखेगा ।

<FilesMatch "\.pdf$">
ForceType applicaton/octet-stream
Header set Content-Disposition attachment
</FilesMatch>

क्या यह आपके सभी PDF को जबरदस्ती डाउनलोड नहीं करेगा?
टेकब्रैट

1
@TecBrat हां, लेकिन यही ओपी ने पूछा था। यदि आप केवल कुछ PDF को सीमित करना चाहते हैं, तो ^\.pdf$नियमित अभिव्यक्ति को संपादित करें ।
रोब डब्ल्यू

1
@TecBrat या .htaccess फ़ाइल को केवल सबफ़ोल्डर में रखें जहाँ इस व्यवहार की आवश्यकता है।
हाबाकुक

14

मुझे सादे पुराने एचटीएमएल और जावास्क्रिप्ट / jQuery के साथ ऐसा करने का एक तरीका मिला जो इनायत से घटता है। IE7-10, सफारी, क्रोम और FF में परीक्षण किया गया:

एचटीएमएल डाउनलोड लिंक के लिए:

<p>Thanks for downloading! If your download doesn't start shortly, 
<a id="downloadLink" href="...yourpdf.pdf" target="_blank" 
type="application/octet-stream" download="yourpdf.pdf">click here</a>.</p>

jQuery (शुद्ध जावास्क्रिप्ट कोड अधिक क्रिया होगा) जो एक छोटी सी देरी के बाद लिंक पर क्लिक करने का अनुकरण करता है:

var delay = 3000;
window.setTimeout(function(){$('#downloadLink')[0].click();},delay);

इसे और अधिक मजबूत बनाने के लिए आप HTML5 फीचर डिटेक्शन जोड़ सकते हैं और यदि यह नहीं है तो window.open()फाइल के साथ एक नई विंडो खोलने के लिए उपयोग करें।


5

यह कुंजी है:

header("Content-Type: application/octet-stream");

पीडीएफ फाइल भेजते समय कंटेंट-टाइप एप्लिकेशन / एक्स-पीडीएफ-डॉक्यूमेंट या एप्लिकेशन / पीडीएफ भेजा जाता है। Adobe Reader आमतौर पर इस MIME प्रकार के लिए हैंडलर सेट करता है ताकि कोई भी PDF MIME प्रकार प्राप्त होने पर ब्राउज़र दस्तावेज़ को Adobe Reader को पास कर दे।


3

मुझे पता है कि मुझे इसका जवाब देने में बहुत देर हो चुकी है, लेकिन मुझे जावास्क्रिप्ट में ऐसा करने के लिए एक हैक मिला।

function downloadFile(src){
    var link=document.createElement('a');
    document.body.appendChild(link);
    link.href= src;
    link.download = '';
    link.click();
}

0

इसे इस्तेमाल करे:

<a href="pdf_server_with_path.php?file=pdffilename&path=http://myurl.com/mypath/">Download my eBook</a>

Pdf_server_with_path.php के अंदर का कोड है:

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
$path = $_GET["path"];
$fullfile = $path.$file;

header("Content-Disposition: attachment; filename=" . Urlencode($file));   
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . Filesize($fullfile));
flush(); // this doesn't really matter.
$fp = fopen($fullfile, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp);

0

यहाँ एक अलग दृष्टिकोण है। मैं वेब सर्वर लॉजिक का उपयोग करने के लिए ब्राउज़र समर्थन पर भरोसा करने या एप्लिकेशन परत पर इसे संबोधित करने के बजाय पसंद करता हूं।

यदि आप अपाचे का उपयोग कर रहे हैं, और संबंधित निर्देशिका में एक .htaccess फ़ाइल डाल सकते हैं, तो आप नीचे दिए गए कोड का उपयोग कर सकते हैं। बेशक, आप इसे httpd.conf में डाल सकते हैं, यदि आपके पास इसकी पहुँच है।

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

FilesMatch का निर्देश सिर्फ एक regex है, इसलिए इसे आप जितना चाहें उतना ही सेट किया जा सकता है, या आप अन्य एक्सटेंशन में जोड़ सकते हैं।

ऊपर की PHP लिपियों में पहली पंक्ति के रूप में हैडर लाइन वही काम करती है। यदि आपको सामग्री-प्रकार की लाइनें सेट करने की आवश्यकता है, तो आप उसी तरीके से कर सकते हैं, लेकिन मुझे यह आवश्यक नहीं लगा।


0

मैंने पीडीएफ फाइल के पूरे यूआरएल का उपयोग करके खदान को हल किया (केवल फाइल का नाम या स्थान डालने के लिए href करने के लिए): a href = "domain। Com / pdf / filename.pdf"


0

अगर आपको डाउनलोड दर सीमित करने की आवश्यकता है, तो इस कोड का उपयोग करें !!

<?php
$local_file = 'file.zip';
$download_file = 'name.zip';

// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if(file_exists($local_file) && is_file($local_file))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);

flush();
$file = fopen($local_file, "r");
while(!feof($file))
{
    // send the current file part to the browser
    print fread($file, round($download_rate * 1024));
    // flush the content to the browser
    flush();
    // sleep one second
    sleep(1);
}
fclose($file);}
else {
die('Error: The file '.$local_file.' does not exist!');
}

?>

अधिक जानकारी के लिए यहां क्लिक करें


0
<!DOCTYPE html>  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
    <title>File Uploader</title>  
    <script src="../Script/angular1.3.8.js"></script>  
    <script src="../Script/angular-route.js"></script>  
    <script src="../UserScript/MyApp.js"></script>  
    <script src="../UserScript/FileUploder.js"></script>  
    <>  
        .percent {  
            position: absolute;  
            width: 300px;  
            height: 14px;  
            z-index: 1;  
            text-align: center;  
            font-size: 0.8em;  
            color: white;  
        }  

        .progress-bar {  
            width: 300px;  
            height: 14px;  
            border-radius: 10px;  
            border: 1px solid #CCC;  
            background-image: -webkit-gradient(linear, left top, left bottom, from(#6666cc), to(#4b4b95));  
            border-image: initial;  
        }  

        .uploaded {  
            padding: 0;  
            height: 14px;  
            border-radius: 10px;  
            background-image: -webkit-gradient(linear, left top, left bottom, from(#66cc00), to(#4b9500));  
            border-image: initial;  
        }  
    </>  
</head>  
<body ng-app="MyApp" ng-controller="FileUploder">  
    <div>  
        <table ="width:100%;border:solid;">  
            <tr>  
                <td>Select File</td>  
                <td>  
                    <input type="file" ng-model-instant id="fileToUpload" onchange="angular.element(this).scope().setFiles(this)" />  
                </td>  
            </tr>  
            <tr>  
                <td>File Size</td>  
                <td>  
                    <div ng-repeat="file in files.slice(0)">  
                        <span ng-switch="file.size > 1024*1024">  
                            <span ng-switch-when="true">{{file.size / 1024 / 1024 | number:2}} MB</span>  
                            <span ng-switch-default>{{file.size / 1024 | number:2}} kB</span>  
                        </span>  
                    </div>  
                </td>  
            </tr>             
            <tr>  
                <td>  
                    File Attach Status  
                </td>  
                <td>{{AttachStatus}}</td>  
            </tr>  
            <tr>  
                <td>  
                    <input type="button" value="Upload" ng-click="fnUpload();" />  
                </td>  
                <td>  
                    <input type="button" value="DownLoad" ng-click="fnDownLoad();" />  
                </td>  
            </tr>  
        </table>  
    </div>  
</body>  
</html>   

1
आपको यह बताना चाहिए कि आपने अपने कोड में क्या प्रदान किया है। संक्षेप में भी यदि विवरण में संभव नहीं है या विवरण में आवश्यक नहीं है।
सूरज कुमार

-1

रूबी ऑन रेल्स एप्लिकेशन (विशेष रूप से प्रॉन रत्न और प्रॉनटो रेल्स प्लगइन जैसे कुछ के साथ), आप इसे स्क्रिप्ट पर पूर्ण (पिछले PHP उदाहरण की तरह) से थोड़ा अधिक पूरा कर सकते हैं।

आपके नियंत्रक में:

def index

 respond_to do |format|
   format.html # Your HTML view
   format.pdf { render :layout => false }
 end
end

रेंडर: लेआउट => गलत भाग ब्राउज़र को बताता है कि "क्या आप इस फ़ाइल को डाउनलोड करना चाहते हैं?" पीडीएफ रेंडर करने के प्रयास के बजाय शीघ्र। तब आप फ़ाइल को सामान्य रूप से लिंक कर पाएंगे: http://mysite.com/myawesomepdf.pdf


यह कोड कहाँ लिखा है? कौन सा नियंत्रक, मैं PHP के लिए नया हूँ कृपया समझाएँ।
प्रशांत

@Prashant यह PHP नहीं है, यह रूबी ऑन रेल्स है।
रोजगार

@Prashant: अगर आपको PHP उदाहरण की आवश्यकता है, तो थ्रेड को आगे देखें, लेकिन कृपया टिप्पणियों के बारे में पढ़ें कि वे कैसे असुरक्षित हो सकते हैं।
इवान डोनोवन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.