Làm cách nào để buộc các tệp mở trong trình duyệt thay vì tải xuống (PDF)?


208

Có cách nào để buộc các tệp PDF mở trong trình duyệt khi tùy chọn "Hiển thị PDF trong trình duyệt" không được chọn không?

Tôi đã thử sử dụng thẻ nhúng và iframe, nhưng nó chỉ hoạt động khi tùy chọn đó được chọn.

Tôi có thể làm gì?

Câu trả lời:


417

Để cho trình duyệt biết rằng tệp nên được xem trong trình duyệt, phản hồi HTTP phải bao gồm các tiêu đề sau:

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

Để tải tệp chứ không phải xem:

Content-Type: application/pdf
Content-Disposition: attachment; filename="filename.pdf"

Các trích dẫn xung quanh tên tệp là bắt buộc nếu tên tệp chứa các ký tự đặc biệt như filename[1].pdfcó thể phá vỡ khả năng xử lý phản hồi của trình duyệt.

Cách bạn đặt các tiêu đề phản hồi HTTP sẽ phụ thuộc vào máy chủ HTTP của bạn (hoặc, nếu bạn đang tạo phản hồi PDF từ mã phía máy chủ: ngôn ngữ lập trình phía máy chủ của bạn).


13
Để bắt buộc tải xuống, tôi sử dụng Content-Type: application / octet-stream.
Papick G. Taboada

25
@ PapickG.Taboada nhưng sau đó hệ thống của người dùng có thể không biết loại tệp. Ví dụ: một số người dùng có thể đã chọn "Luôn mở các tệp loại này" cho các tệp PDF. Có lẽ nếu bạn muốn ghi đè tùy chọn của người dùng thì octet-stream sẽ là cách tốt nhất, nhưng đưa ra loại chính xác và tên tệp được đề xuất là cách "chính xác" để cung cấp tải xuống.
ColinM

2
xin chào @ColinM Tôi hơi bối rối ở đây ... chúng tôi đang gặp sự cố khi hiển thị pdf, nó chỉ đưa ra một văn bản bị xáo trộn. nơi chúng tôi đặt Loại nội dung: application / pdf Content-Dispose: inline; "filename.pdf"? 'cos, chúng tôi tải nó lên bằng mã angular-js. Vì vậy, câu hỏi của tôi là loại nội dung nên được đặt trước khi tải lên? Ngoài ra, chúng tôi chỉ nhận được một liên kết từ nhóm phụ trợ, một url cung cấp đường dẫn tệp mà chúng tôi mở trong tab mới bằng cách sử dụng: window.open (url, '_blank'). Focus ();
Kailas

3
@Kailas Tôi không hiểu bạn đang cố gắng làm gì .. Câu trả lời là đề cập đến các tiêu đề mà máy chủ sẽ gửi cho khách hàng khi trả lời yêu cầu HTTP cho tệp PDF. Các tiêu đề này không có tác dụng đối với việc tải lên tệp, bạn cần có mã phía sau url đặt các tiêu đề mỗi khi được khách hàng tải xuống.
ColinM

1
@ColinM Cảm ơn bạn thân, bạn đã nói đúng, vấn đề khi chúng tôi gỡ lỗi là loại mime được đặt trong khi tải lên các tệp. Điều này nên được thực hiện bởi nhóm back-end. Tôi đã cố gắng lấy mã về cách thêm tiêu đề trong tập lệnh java nhưng không thành công. Cảm ơn, vì tôi đã xóa ý tưởng thực sự khỏi bạn ... :)
Kailas

19

Nếu bạn đang sử dụng HTML5 (và tôi đoán ngày nay mọi người đều sử dụng điều đó), có một thuộc tính được gọi download.

Ví dụ,

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

Đây filenamelà tùy chọn, nhưng nếu được cung cấp, nó sẽ lấy tên này cho tệp đã tải xuống.


2
Nếu bạn có quyền kiểm soát mã máy chủ, bạn nên sử dụng 'tệp đính kèm' vì điều này sẽ cho phép sử dụng cùng mã tạo tên tệp. Nếu bạn không có quyền kiểm soát máy chủ thì đây là một giải pháp tốt.
Barshe Roussy

Đây là một giải pháp tuyệt vời cho vấn đề, tuy nhiên, như mọi khi, IE đang ngăn chúng tôi sử dụng nó: caniuse.com/#search=d
Rory McCrossan

1
Điều quan trọng cần lưu ý là điều này không hoạt động trên các tên miền (ví dụ: chính sách cùng nguồn gốc được thực hiện). Nếu tải xuống từ một tên miền, thuộc tính tải xuống sẽ không hoạt động nếu nội dung được lưu trữ trên một tên miền khác. CORS có thể cho phép nội dung đó đi qua (chưa được thử nghiệm).
vol7ron

59
Điều này hoàn toàn trái ngược với những gì OP yêu cầu :)
Chuck Le Mông

1
Có hình! : \ Tôi hiểu câu hỏi sai và trả lời. Nhưng nhiều người hạ cánh ở đây chỉ tìm thấy điều ngược lại, đó là lý do tại sao không chỉnh sửa / xóa câu trả lời.
Akshay

16

Loại chính xác là application/pdfcho PDF, không phải application/force-download. Điều này trông giống như một hack cho một số trình duyệt cũ. Luôn luôn sử dụng đúng mimetype nếu bạn có thể.

Nếu bạn có quyền kiểm soát mã máy chủ:

  • Buộc tải xuống / nhắc: sử dụng header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • Trình duyệt cố gắng mở nó: sử dụng header("Content-Disposition", "inline; filename=myfilename.myextension");

Không kiểm soát mã máy chủ:

LƯU Ý: Tôi thích đặt tên tệp ở phía máy chủ vì bạn có thể có nhiều thông tin hơn và có thể sử dụng mã chung.


2

Nếu bạn có Apache, hãy thêm nó vào .htaccesstệp:

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

Làm thế nào chúng ta có thể thêm nhiều phần mở rộng? Tôi cũng muốn thêm phần mở rộng DOC và XLS. Vui lòng gợi ý cho tôi. Cảm ơn trước.
Kam thịt

Điều đó ngược lại với những gì được yêu cầu
Quentin

1

Rất tiếc, đã có lỗi đánh máy trong bài viết trước của tôi.

    header("Content-Type: application/force-download");
    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=\"".$name."\";");

Nếu bạn không muốn trình duyệt nhắc người dùng thì hãy sử dụng "nội tuyến" cho chuỗi thứ ba thay vì "tệp đính kèm". Inline hoạt động rất tốt. Màn hình PDF hiển thị ngay lập tức mà không yêu cầu người dùng nhấp vào Mở. Tôi đã sử dụng "tệp đính kèm" và điều này sẽ nhắc người dùng mở, lưu. Tôi đã cố gắng thay đổi cài đặt trình duyệt nhưng nó không ngăn được lời nhắc.


4
Bài trước là gì?
Peter Mortensen

0

Cái này dành cho ASP.NET MVC

Trong trang cshtml của bạn:

<section>
    <h4><a href="@Url.Action("Download", "Document", new { id = @Model.GUID })"><i class="fa fa-download"></i> @Model.Name</a></h4>
    <object data="@Url.Action("View", "Document", new { id = @Model.GUID })" type="application/pdf" width="100%" height="800" class="col-md-12">
        <h2>Your browser does not support viewing PDFs, click on the link above to download the document.</h2>
    </object>
</section>

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

public ActionResult Download(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        return File(model.FilePath, "application/pdf", model.FileName);
    }

public FileStreamResult View(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        FileStream fs = new FileStream(model.FilePath, FileMode.Open, FileAccess.Read);

        return File(fs, "application/pdf");
    }

-1

Mặc dù các tính năng sau hoạt động tốt trên firefox, nhưng nó KHÔNG hoạt động trên các trình duyệt chrome và di động.

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

Để khắc phục lỗi chrome & trình duyệt di động, hãy làm như sau:

  • Lưu trữ các tập tin của bạn trên một thư mục trong dự án của bạn
  • Sử dụng Trình xem Google PDF

Trình xem Google PDF có thể được sử dụng như vậy:

<iframe src="http://docs.google.com/gview?url=http://example.com/path/to/my/directory/pdffile.pdf&embedded=true" frameborder="0"></iframe>

-4

Mở download.php từ rootfile.

Sau đó đi đến dòng 186 và thay đổi nó như sau:

        if(preg_match("/\.jpg|\.gif|\.png|\.jpeg/i", $name)){
            $mime = getimagesize($download_location);
            if(!empty($mime)) {
                header("Content-Type: {$mime['mime']}");
            }
        }
        elseif(preg_match("/\.pdf/i", $name)){
            header("Content-Type: application/force-download");
            header("Content-type: application/pdf");
            header("Content-Disposition: inline; filename=\"".$name."\";");
        }

        else{
            header("Content-Type: application/force-download");
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename=\"".$name."\";");
        }

7
Không đề cập đến việc họ sử dụng PHP. Điều gì xảy ra nếu phụ trợ của họ là trong Python hoặc .NET?
Maxime Rouiller

1
... Nói về lĩnh vực bên trái. Anh ấy thậm chí không nói những gì anh ấy nói về khuôn khổ.
Archonic

-4

Bạn có thể làm điều này theo cách sau:

<a href="path to PDF file">Open PDF</a>

Nếu tệp PDF nằm trong một số thư mục và thư mục đó không có quyền truy cập trực tiếp vào các tệp trong thư mục đó thì bạn phải bỏ qua một số hạn chế truy cập .htaccesstệp bằng cách sử dụng cài đặt tệp theo cách này:

<FilesMatch ".*\.(jpe?g|JPE?G|gif|GIF|png|PNG|swf|SWF|pdf|PDF)$" >
    Order Allow,Deny
    Allow from all
</FilesMatch>

Nhưng bây giờ cho phép chỉ định tập tin cần thiết.

Tôi đã sử dụng mã này và nó hoạt động hoàn hảo.


Không đề cập đến việc họ sử dụng Apache. Nếu họ sử dụng IIS thì sao? Hay là Express?
Maxime Rouiller


-7

Đây là một phương pháp khác để buộc một tệp phải xem trong trình duyệt trong PHP:

$extension = pathinfo($file_name, PATHINFO_EXTENSION);
$url = 'uploads/'.$file_name;
        echo '<html>'
                .header('Content-Type: application/'.$extension).'<br>'
                .header('Content-Disposition: inline; filename="'.$file_name.'"').'<br>'
                .'<body>'
                .'<object   style="overflow: hidden; height: 100%;
             width: 100%; position: absolute;" height="100%" width="100%" data="'.$url.'" type="application/'.$extension.'">
                    <embed src="'.$url.'" type="application/'.$extension.'" />
             </object>'
            .'</body>'
            . '</html>';

1
headerkhông hoạt động sau khi bạn bắt đầu xuất nội dung yêu cầu (và nó không trả về một chuỗi để nối trong tài liệu HTML)
Quentin

-9

Chỉ cần mở Adobe Reader, menu → Chỉnh sửaTùy chọnInternet , sau đó thay đổi sang chế độ trình duyệt hoặc để được hướng dẫn chi tiết trên các trình duyệt khác nhau, hãy thử Hiển thị PDF trong trình duyệt | Acrobat, Acrobat Reader .


3
Điều gì xảy ra nếu bạn không sử dụng AdobeReader hoặc không sử dụng windows? Bạn trả lời sẽ không hoạt động. Hơn nữa, nó yêu cầu người dùng thay đổi cài đặt của họ, điều mà bạn không thể làm trong thế giới thực.
Móng vuốt

-12

Nếu bạn liên kết đến .PDF, nó sẽ mở trong trình duyệt.
Nếu hộp được bỏ chọn, nó sẽ liên kết với .zip để buộc tải xuống.

Nếu .zip không phải là một tùy chọn, thì hãy sử dụng các tiêu đề trong PHP để buộc tải xuống

header('Content-Type: application/force-download'); 
header('Content-Description: File Transfer'); 

Có, nhưng tôi cần một cách để buộc phải mở trong trình duyệt không tải xuống. Tôi không biết nếu nó có thể.
elloalisboa

2
Nếu bạn không buộc nó tải xuống, thì bạn buộc nó phải mở trong trình duyệt. Nếu nó không mở trong trình duyệt, thì đó là vì người dùng có cài đặt cụ thể mà bạn không thể ghi đè hoặc họ không có phần mềm đọc PDF.
Kirk Strobeck

1
Trên thực tế, xem câu trả lời của tôi.
Gabriel Ryan Nahmias

21
Cái này sai. Không có ứng dụng / lực lượng tải xuống. Bạn cũng có thể sử dụng alskjdsdjk / aljksdlasdj. Trình duyệt sẽ tải xuống vì nó không biết loại mime này. Loại mime phù hợp để tải xuống sẽ cho tôi ứng dụng / octet-stream
Papick G. Taboada
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.