ฉันจะบังคับให้เปิดไฟล์ในเบราว์เซอร์แทนการดาวน์โหลด (PDF) ได้อย่างไร


210

มีวิธีบังคับให้เปิดไฟล์ PDF ในเบราว์เซอร์เมื่อไม่ได้เลือกตัวเลือก "แสดง PDF ในเบราว์เซอร์" หรือไม่?

ฉันลองใช้แท็กฝังและ iframe แต่ใช้ได้เฉพาะเมื่อตรวจสอบตัวเลือกนั้นแล้ว

ฉันควรทำอย่างไร

คำตอบ:


419

หากต้องการระบุเบราว์เซอร์ที่ควรดูไฟล์ในเบราว์เซอร์การตอบสนอง HTTP ควรมีส่วนหัวเหล่านี้:

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

หากต้องการดาวน์โหลดไฟล์แทนที่จะดู:

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

จำเป็นต้องใช้อัญประกาศรอบชื่อไฟล์ถ้าชื่อไฟล์มีอักขระพิเศษเช่นfilename[1].pdfซึ่งอาจทำลายความสามารถของเบราว์เซอร์ในการจัดการการตอบสนอง

วิธีที่คุณตั้งค่าส่วนหัวการตอบกลับ HTTP จะขึ้นอยู่กับเซิร์ฟเวอร์ HTTP ของคุณ (หรือหากคุณกำลังสร้างการตอบกลับ PDF จากรหัสฝั่งเซิร์ฟเวอร์: ภาษาการเขียนโปรแกรมฝั่งเซิร์ฟเวอร์ของคุณ)


13
หากต้องการบังคับการดาวน์โหลดฉันควรใช้ Content-Type: application / octet-stream
Papick G. Taboada

25
@ PapickG.Taboada แต่ระบบของผู้ใช้อาจไม่ทราบประเภทไฟล์ เช่นผู้ใช้บางคนอาจเลือกที่จะ "เปิดไฟล์ประเภทนี้เสมอ" สำหรับไฟล์ PDF บางทีหากคุณต้องการแทนที่การตั้งค่าของผู้ใช้ octet-stream ก็จะเป็นไปได้ แต่การให้ประเภทที่ถูกต้องและชื่อไฟล์ที่แนะนำคือวิธีที่ "ถูกต้อง" เพื่อให้ดาวน์โหลด
ColinM

2
สวัสดี @ColinM ฉันสับสนเล็กน้อยที่นี่ ... เรากำลังมีปัญหาในการเรนเดอร์ pdf มันแค่ให้ข้อความที่มีสัญญาณรบกวน เราจะตั้งค่า Content-Type: application / pdf Content-Disposition: inline; "filename.pdf"? เพราะเราอัปโหลดโดยใช้รหัส angular-js ดังนั้นคำถามของฉันควรตั้งประเภทเนื้อหาก่อนที่จะอัพโหลด? และเรายังได้รับลิงค์จากทีมแบ็กเอนด์ซึ่งเป็น URL ที่ให้เส้นทางไฟล์ที่เราเปิดในแท็บใหม่โดยใช้: window.open (url, '_blank'). focus ();
Kailas

3
@Kailas ฉันไม่เข้าใจสิ่งที่คุณกำลังพยายามทำ .. คำตอบคือส่วนหัวที่เซิร์ฟเวอร์ควรส่งถึงลูกค้าเมื่อตอบกลับคำขอ HTTP สำหรับไฟล์ PDF ส่วนหัวเหล่านี้ไม่มีผลกับการอัปโหลดไฟล์คุณต้องมีรหัสที่อยู่เบื้องหลัง url ที่ตั้งค่าส่วนหัวทุกครั้งที่ลูกค้าดาวน์โหลด
ColinM

1
@ColinM ขอบคุณเพื่อนคุณบอกว่าถูกต้องปัญหาเมื่อเราดีบั๊กคือประเภท mime ถูกตั้งค่าในขณะอัพโหลดไฟล์ สิ่งนี้ควรทำโดยทีมแบ็คเอนด์ ฉันพยายามรับรหัสเกี่ยวกับวิธีเพิ่มส่วนหัวในจาวาสคริปต์ แต่ไม่ประสบความสำเร็จ ขอบคุณที่ฉันได้รับความคิดจริงจากคุณ ... :)
Kailas

19

หากคุณกำลังใช้ HTML5 (และฉันเดาว่าทุกคนในปัจจุบันใช้มัน) มีคุณสมบัติที่เรียกว่า downloadมีคุณลักษณะที่เรียกว่า

ตัวอย่างเช่น,

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

ที่นี่filenameเป็นตัวเลือก แต่ถ้ามีจะใช้ชื่อนี้สำหรับไฟล์ที่ดาวน์โหลด


2
หากคุณสามารถควบคุมรหัสเซิร์ฟเวอร์ได้คุณควรใช้ 'attachement' เพราะจะทำให้สามารถใช้รหัสการสร้างชื่อไฟล์เดียวกันได้ หากคุณไม่สามารถควบคุมเซิร์ฟเวอร์นี่เป็นทางออกที่ดี
Christophe Roussy

นี่เป็นวิธีแก้ปัญหาที่ยอดเยี่ยมอย่างไรก็ตามเช่นเคย IE กำลังรั้งเราไว้ไม่ให้ใช้งาน: caniuse.com/#search=download
Rory McCrossan

1
สิ่งสำคัญที่ควรทราบคือสิ่งนี้ไม่สามารถทำงานได้ข้ามโดเมน หากการดาวน์โหลดจากโดเมนหนึ่งคุณลักษณะการดาวน์โหลดจะไม่ทำงานหากเนื้อหาถูกเก็บไว้ในโดเมนอื่น CORS อาจอนุญาตให้เนื้อหานั้นผ่าน (ยังไม่ได้ทดสอบ)
ฉบับที่ 7

59
นี่คือตัวอักษรตรงข้ามของสิ่ง OP จะขอ :)
ชัคเลอก้น

1
ใช่แล้ว! : \ ฉันเข้าใจคำถามผิดและตอบ แต่ผู้คนจำนวนมากลงมาที่นี่เพื่อค้นหาสิ่งที่ตรงกันข้ามนั่นคือเหตุผลที่ไม่ได้แก้ไข / ลบคำตอบ
Akshay

16

ประเภทที่ถูกต้องapplication/pdfสำหรับ PDF ไม่ใช่application/force-downloadไม่ ดูเหมือนแฮ็คสำหรับเบราว์เซอร์รุ่นเก่าบางตัว ให้ใช้ชนิด mime ที่ถูกต้องทุกครั้งถ้าทำได้

หากคุณมีการควบคุมรหัสเซิร์ฟเวอร์:

  • บังคับให้ดาวน์โหลด / พรอมต์: ใช้ header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • เบราว์เซอร์พยายามเปิด: ใช้ header("Content-Disposition", "inline; filename=myfilename.myextension");

ไม่มีการควบคุมรหัสเซิร์ฟเวอร์:

  • ใช้แอตทริบิวต์ HTML5 ดาวน์โหลด มันใช้ชื่อไฟล์ที่กำหนดเองที่ระบุไว้ในด้านมุมมอง

หมายเหตุ: ฉันชอบการตั้งชื่อไฟล์ทางฝั่งเซิร์ฟเวอร์เนื่องจากคุณอาจมีข้อมูลเพิ่มเติมและสามารถใช้รหัสทั่วไปได้


2

หากคุณมี Apache เพิ่มสิ่งนี้ใน .htaccessไฟล์:

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

เราจะเพิ่มหลายนามสกุลได้อย่างไร ฉันต้องการเพิ่ม DOC และ XLS ด้วย กรุณาแนะนำฉัน ขอบคุณล่วงหน้า.
Kamlesh

ตรงข้ามกับสิ่งที่ถูกขอ
เควนติน

1

อ๊ะเกิดข้อผิดพลาดในการพิมพ์ในโพสต์ก่อนหน้าของฉัน

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

หากคุณไม่ต้องการให้เบราว์เซอร์แจ้งผู้ใช้ให้ใช้ "อินไลน์" สำหรับสตริงที่สามแทน "ไฟล์แนบ" Inline ทำงานได้ดีมาก PDF จะแสดงทันทีโดยไม่ต้องให้ผู้ใช้คลิกที่ Open ฉันใช้ "ไฟล์แนบ" และสิ่งนี้จะแจ้งให้ผู้ใช้ทราบถึงการเปิด, บันทึก ฉันพยายามที่จะเปลี่ยนการตั้งค่าเบราว์เซอร์มันไม่ได้ป้องกันพรอมต์


4
โพสต์ก่อนหน้านี้คืออะไร
Peter Mortensen

0

นี่สำหรับ ASP.NET MVC

ในหน้า cshtml ของคุณ:

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

ในตัวควบคุมของคุณ:

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

ในขณะที่ข้อมูลต่อไปนี้ทำงานได้ดีกับ Firefox แต่มันไม่สามารถทำงานได้ใน Chrome และเบราว์เซอร์มือถือ

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

หากต้องการแก้ไขข้อผิดพลาดของเบราว์เซอร์ Chrome & มือถือให้ทำดังนี้:

  • จัดเก็บไฟล์ของคุณในไดเรกทอรีในโครงการของคุณ
  • ใช้โปรแกรมดู PDF ของ Google

Google PDF Viewer สามารถใช้ได้ดังนี้:

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

-4

เปิด downloads.php จาก rootfile

จากนั้นไปที่บรรทัด 186 และเปลี่ยนเป็นต่อไปนี้:

        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
ไม่พูดถึงว่าพวกเขาใช้ PHP จะเป็นอย่างไรถ้าแบ็กเอนด์ของพวกเขาอยู่ใน Python หรือ. NET
Maxime Rouiller

1
... พูดถึงเรื่องนอกทุ่ง เขาไม่ได้พูดถึงกรอบที่เขาพูดถึง
Archonic

-4

คุณสามารถทำได้ด้วยวิธีต่อไปนี้:

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

หากไฟล์ PDF อยู่ในโฟลเดอร์บางโฟลเดอร์และโฟลเดอร์นั้นไม่ได้รับอนุญาตให้เข้าถึงไฟล์ในโฟลเดอร์นั้นโดยตรงคุณต้องข้ามข้อ จำกัด การเข้าถึง.htaccessไฟล์โดยใช้การตั้งค่าไฟล์ด้วยวิธีนี้:

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

แต่ตอนนี้อนุญาตเพียงบางอย่างไฟล์ที่จำเป็น

ฉันใช้รหัสนี้และทำงานได้อย่างสมบูรณ์


ไม่พูดถึงว่าพวกเขาใช้ Apache ถ้าพวกเขาใช้ IIS ล่ะ หรือด่วน
Maxime Rouiller


-7

นี่เป็นอีกวิธีในการบังคับให้ไฟล์ดูในเบราว์เซอร์ใน 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
headerไม่ทำงานหลังจากที่คุณเริ่มต้นการแสดงผลของร่างกายร้องขอ (และไม่กลับสตริงสำหรับเชื่อมโยงในเอกสาร HTML)
เควนติน

-9

เพียงเปิด Adobe Reader เมนู→ แก้ไข →การตั้งค่าอินเทอร์เน็ตจากนั้นเปลี่ยนเป็นโหมดเบราว์เซอร์หรือสำหรับคำแนะนำโดยละเอียดเกี่ยวกับเบราว์เซอร์ที่แตกต่างกันลองแสดง PDF ในเบราว์เซอร์ | Acrobat, Acrobat Reader


3
ถ้าคุณไม่ใช้ AdobeReader หรือไม่ใช้ windows ล่ะ คำตอบของคุณจะไม่ทำงาน ยิ่งไปกว่านั้นมันต้องขอให้ผู้ใช้เปลี่ยนการตั้งค่าของพวกเขาซึ่งคุณไม่สามารถทำได้ในโลกแห่งความจริง
Clawfire

-12

หากคุณลิงก์ไปยัง. PDF มันจะเปิดขึ้นในเบราว์เซอร์
หากไม่มีการทำเครื่องหมายในช่องควรลิงก์ไปยัง. zip เพื่อบังคับให้ดาวน์โหลด

หาก. zip ไม่ใช่ตัวเลือกให้ใช้ส่วนหัวใน PHP เพื่อบังคับการดาวน์โหลด

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

ใช่ แต่ฉันต้องการวิธีบังคับให้เปิดในเบราว์เซอร์ไม่ให้ดาวน์โหลด ฉันไม่มีความคิดถ้าเป็นไปได้
elloalisboa

2
หากคุณไม่ได้บังคับให้ดาวน์โหลดคุณจะบังคับให้เปิดในเบราว์เซอร์ หากไม่เปิดในเบราว์เซอร์อาจเป็นเพราะผู้ใช้มีการตั้งค่าเฉพาะซึ่งคุณไม่สามารถแทนที่ได้หรือไม่มีซอฟต์แวร์อ่าน PDF
Kirk Strobeck

1
ที่จริงแล้วเห็นคำตอบของฉัน
Gabriel Ryan Nahmias

21
นี่เป็นสิ่งที่ผิด ไม่มีแอปพลิเคชัน / แรงดาวน์โหลด คุณสามารถใช้ alskjdsdjk / aljksdlasdj ได้เช่นกัน เบราว์เซอร์จะดาวน์โหลดเพราะมันไม่รู้ประเภท mime นี้ ประเภท mime ที่ถูกต้องสำหรับการดาวน์โหลดจะให้ฉันสมัคร / octet-stream
Papick G. Taboada
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.