113

Tôi đang cung cấp liên kết của một tệp pdf trên trang web của tôi để tải xuống, như dưới đây

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

Vấn đề là khi người dùng nhấp vào liên kết này thì

  • Nếu người dùng đã cài đặt Adobe Acrobat, thì nó sẽ mở tệp trong cùng cửa sổ trình duyệt trong Adobe Reader.
  • Nếu Adobe Acrobat chưa được cài đặt thì nó sẽ bật lên cho người dùng để tải xuống tệp.

Nhưng tôi muốn nó luôn bật lên cho người dùng tải xuống, bất kể "Adobe acrobat" có được cài đặt hay không.

Xin vui lòng cho tôi biết làm thế nào tôi có thể làm điều này?

|
114

Thay vì liên kết đến tệp .PDF, thay vào đó hãy làm một cái gì đó như

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

đầu ra tiêu đề tùy chỉnh, mở tệp PDF (an toàn nhị phân) và in dữ liệu lên trình duyệt của người dùng, sau đó họ có thể chọn lưu tệp PDF bất chấp cài đặt trình duyệt của họ. Pdf_server.php sẽ trông như thế này:

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

PS: và rõ ràng chạy một số kiểm tra độ tỉnh táo trên biến "tệp" để ngăn mọi người ăn cắp tệp của bạn như không chấp nhận tiện ích mở rộng tệp, từ chối gạch chéo, thêm .pdf vào giá trị

|
  • 1

    Tôi đang phải đối mặt với một vấn đề khác, đó là tệp của tôi được đặt tại /products/brochure/myfile.pdf Tôi đang đưa ra biến tệp $ là $ file_path = $ _SERVER ['DOCUMENT_ROOT']. '/ Products / brochure /'. $ tập tin; nhưng nó tải xuống tệp dưới dạng "% 2Fvar% 2Fwww% 2Fweb15% 2Fweb% 2Fproducts% 2Fbrochure% 2myfile.pdf"

    – Trịnh Phương Nhi 10:11:34 13/12/2008
  • 1

    @TravisO "Content-type: application/force-download"không được liệt kê ở bất cứ đâu tại đây: iana.org/assignments/media-types/application Đó là một tiêu đề hoàn toàn không có thật. Xin đừng trang điểm và gửi chúng. Bạn có thể cập nhật câu trả lời của bạn. Cảm ơn.

    – Lý Phụng Yến 15:37:26 28/08/2013
  • 1

    Hãy cẩn thận khi sử dụng mã này nguyên văn, mặc dù. Điều này giới thiệu một lỗ hổng LFI nghiêm trọng, khi bạn chuyển trực tiếp các biến GET fopen.

    – Bùi Hoàng Khánh 12:48:57 25/02/2015
  • 1

    Mã này có khả năng nguy hiểm theo một cách khác. Nếu bạn chuyển các liên kết HTTP đến fopen, tôi nghĩ rằng nó sẽ truy xuất tệp từ một máy chủ khác. Kẻ tấn công có thể sử dụng để quét mạng nội bộ của bạn để tìm các tệp PDF bị lộ.

    – Hoàng Hoàng Kim 12:24:37 04/09/2015
  • 1

    Không đề cập đến việc dễ dàng vượt qua bất kỳ "kiểm tra vệ sinh" nào mà bạn nghĩ rằng bạn sẽ thực hiện với tham số "tệp". Đường dẫn tiêm / thư mục tấn công ngang ngược là rất có thể.

    – Tạ Huyền Trâm 13:18:38 04/09/2015
174

Đây là một vấn đề phổ biến nhưng ít người biết có một giải pháp HTML 5 đơn giản:

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

Trong trường hợp newfilenamelà tên file gợi ý cho người sử dụng để lưu các tập tin. Hoặc nó sẽ mặc định là tên tệp trên máy chủ nếu bạn để trống, như thế này:

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

Khả năng tương thích: Tôi đã thử nghiệm điều này trên Firefox 21 và Iron, cả hai đều hoạt động tốt. Nó có thể không hoạt động trên các trình duyệt không tương thích hoặc lỗi thời HTML5. Trình duyệt duy nhất tôi đã kiểm tra không bắt buộc tải xuống là IE ...

Kiểm tra tính tương thích tại đây: http://caniuse.com/#feat=d Download

|
49

Đừng lặp qua từng dòng tệp. Sử dụng readfile thay thế, nó nhanh hơn. Đây là trang web php: http://php.net/manual/en/feft.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;
}

Đảm bảo vệ sinh biến get của bạn vì ai đó có thể tải xuống một số tệp php ...

|
  • 1

    Hàm readfile thực sự nhanh hơn. Cá nhân tôi khuyên bạn nên sử dụng câu trả lời này thay vì câu trả lời được chấp nhận

    – Lê Ðình Toàn 21:08:28 04/02/2013
25

Thay vì sử dụng tập lệnh PHP, để đọc và xóa tập tin, việc viết lại tiêu đề sẽ gọn gàng hơn .htaccess. Điều này sẽ giữ một URL "đẹp" ( myfile.pdfthay vì download.php?myfile).

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

Tôi đã tìm thấy một cách để làm điều đó với HTML và JavaScript / jQuery cũ đơn giản mà xuống cấp một cách duyên dáng. Đã thử nghiệm trong IE7-10, Safari, Chrome và FF:

HTML cho liên kết tải xuống:

<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 (mã JavaScript thuần sẽ dài dòng hơn) mô phỏng nhấp vào liên kết sau một độ trễ nhỏ:

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

Để làm cho điều này mạnh mẽ hơn, bạn có thể thêm tính năng phát hiện HTML5 và nếu không có thì hãy sử dụng window.open()để mở một cửa sổ mới với tệp.

|
6

Đây là chìa khóa:

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

Ứng dụng loại nội dung / x-pdf-document hoặc application / pdf được gửi trong khi gửi tệp PDF. Adobe Reader thường đặt trình xử lý cho loại MIME này để trình duyệt sẽ chuyển tài liệu tới Adobe Reader khi nhận được bất kỳ loại MIME PDF nào.

|
5

Có một cách dễ dàng hơn trong HTML5: Thêm một Downloadthuộc tính.

Nó được hỗ trợ bởi hầu hết các trình duyệt hiện đại.

<a download href="file.pdf">Download PDF</a> 
|
4

Tôi biết tôi rất muộn để trả lời điều này nhưng tôi đã tìm thấy một bản hack để làm điều này trong javascript.

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

Trong ứng dụng Ruby on Rails (đặc biệt là với thứ gì đó như đá quý Prawn và plugin Prawnto Rails), bạn có thể thực hiện việc này đơn giản hơn một chút so với tập lệnh đầy đủ (như ví dụ PHP trước đây).

Trong bộ điều khiển của bạn:

def index

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

Phần kết xuất: layout => false sẽ cho trình duyệt mở ra "Bạn có muốn tải xuống tệp này không?" nhắc thay vì cố gắng kết xuất PDF. Sau đó, bạn sẽ có thể liên kết đến tệp một cách bình thường: http://mysite.com/myawesomepdf.pdf

|
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>   
|
0

nếu bạn cần giới hạn tốc độ tải xuống, hãy sử dụng mã này !!

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

?>

Để biết thêm thông tin bấm vào đây

|
0

Tôi đã giải quyết vấn đề của tôi bằng cách sử dụng toàn bộ url của tệp PDF (Thay vì chỉ đặt tên tệp hoặc vị trí thành href): a href = "domain. Com / pdf / filename.pdf"

|
0

Đây là một cách tiếp cận khác nhau. Tôi thích thay vì dựa vào hỗ trợ trình duyệt, hoặc giải quyết vấn đề này ở lớp ứng dụng, để sử dụng logic máy chủ web.

Nếu bạn đang sử dụng Apache và có thể đặt tệp .htaccess vào thư mục có liên quan, bạn có thể sử dụng mã bên dưới. Tất nhiên, bạn cũng có thể đặt cái này trong httpd.conf, nếu bạn có quyền truy cập vào đó.

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

Lệnh FilesMatch chỉ là một biểu thức chính quy để nó có thể được đặt chi tiết như bạn muốn hoặc bạn có thể thêm vào các tiện ích mở rộng khác.

Dòng Header thực hiện tương tự như dòng đầu tiên trong các tập lệnh PHP ở trên. Nếu bạn cũng cần đặt các dòng Kiểu nội dung, bạn có thể làm như vậy theo cách tương tự, nhưng tôi không thấy cần thiết.

|
0

Thử đi:

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

Mã bên trong pdf_server_with_path.php là:

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

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.