แสดงไฟล์ PDF ในเบราว์เซอร์ของผู้ใช้ผ่าน PHP / Perl


121

ฉันต้องการแสดงไฟล์ PDF ให้กับผู้ใช้ของฉัน เหตุผลที่ฉันใช้ cgi เพื่อแสดง pdf คือฉันต้องการติดตามการคลิกสำหรับ pdf และปิดบังตำแหน่งจริงของ pdf ที่บันทึกไว้

ฉันค้นหาบนอินเทอร์เน็ตและพบเพียงวิธีแสดงกล่องโต้ตอบบันทึกให้กับผู้ใช้และสร้าง pdf เท่านั้นไม่แสดงไฟล์ให้ผู้ใช้เห็น

สิ่งที่ฉันต้องการคือแสดงให้ผู้ใช้เห็นไฟล์ pdf ของฉันไม่ใช่การสร้างหรือดาวน์โหลด pdf นี่คือสิ่งที่ฉันได้รับจากเอกสาร php อย่างเป็นทางการ:

<?php
header('Content-type: application/pdf');
readfile('the.pdf');
?>

รหัส perl ผลการค้นหาของ Google ของฉันด้วย:

open(PDF, "the.pdf") or die "could not open PDF [$!]";
binmode PDF;
my $output = do { local $/; <PDF> };
close (PDF);

print "Content-Type: application/pdf\n";
print "Content-Length: " .length($output) . "\n\n";
print $output

ถ้าคุณทำกับทับทิมโปรดพูดกับฉัน แต่ฉันไม่แน่ใจว่าเซิร์ฟเวอร์ของฉันรองรับรางหรือไม่

ขออภัยหากโค้ดของฉันอยู่ห่างไกลจากวิธีการแสดง pdf มากเกินไปเนื่องจากฉันไม่รู้อะไรเลยเกี่ยวกับการประมวลผล pdf และวิธีการใช้งานปัญหานี้

สมมติว่าผู้ใช้มีปลั๊กอิน Adobe Reader แล้วจะแก้ไขปัญหาได้อย่างไร?

แก้ไข : ฉันต้องการแสดงไฟล์ pdf ธรรมดา จุดประสงค์หลักของฉัน: ติดตามไฟล์ pdf ของฉันและใช้ URL ที่สวยงาม

แก้ไข : นี่คือรหัส php หลักของฉัน:

<?php
$file='/files/the.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="the.pdf"');
@readfile($file);
?>

แก้ไข : ตอนนี้รหัสใช้งานได้ แต่แถบความคืบหน้าในการโหลด (บนปลั๊กอิน Adobe Reader X) ไม่ปรากฏขึ้น ทำไม? ใครก็ได้ช่วยฉันที นี่คือรหัสหลักของฉัน:

<?php
$file='./files/the.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="the.pdf"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
@readfile($file);
?>

แก้ไข : ปัญหาทั้งหมดของฉันแก้ไขได้ นี่คือรหัสสุดท้าย:

<?php
$file = './path/to/the.pdf';
$filename = 'Custom file name for the.pdf'; /* Note: Always use .pdf at the end. */

header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');

@readfile($file);
?>

ขอบคุณ! :)


4
"show" จะเป็นไปได้ก็ต่อเมื่อไคลเอนต์ติดตั้งปลั๊กอิน Acrobat Reader มิฉะนั้นจะถูกทำหน้าที่เป็นไฟล์ดาวน์โหลดเสมอคุณไม่สามารถทำอะไรได้ การปิดบังเส้นทางของ PDF ก็เป็นไปไม่ได้เช่นกันมันเป็นเรื่องเล็กน้อยที่จะค้นหา กำลังพยายามทำอะไรอยู่? อาจมีทางเลือกอื่นหากเรารู้เพิ่มเติมเกี่ยวกับเป้าหมายของคุณ
Pekka

4
จำเป็นต้องใช้ปลั๊กอิน Adobe Reader เฉพาะในกรณีที่คุณใช้เบราว์เซอร์ที่ไม่รองรับ PDF นอกจากนี้หากไฟล์ PDF ถูกส่งไปยังเบราว์เซอร์ผ่าน PHP / Perl ก็เป็นไปได้มากที่จะบดบังเส้นทาง PDF จริงหรือแม้กระทั่งส่งออกนอก docroot ดังนั้นจึงไม่สามารถเข้าถึงได้โดยตรง
Stephen

1
จำเป็นต้องใช้ Adobe Reader ก็ต่อเมื่อผู้ใช้ใช้เบราว์เซอร์ที่ไม่ได้จัดการ PDF โดยกำเนิด ...
GolezTrol

@ ขั้นตอนนี้เป็นไปได้แน่นอนที่จะบดบังเส้นทางจริง แต่สิ่งที่ OP ดูเหมือนจะต้องการคือการปิดบัง URL เพื่อป้องกันการโจรกรรม
Pekka

สมมติว่าผู้ใช้มีปลั๊กอิน Adobe Reader แล้วจะแก้ไขปัญหาได้อย่างไร?
dimassony

คำตอบ:


49

ฉันคิดว่าคุณต้องการให้ PDF แสดงในเบราว์เซอร์แทนที่จะบังคับให้ดาวน์โหลด หากเป็นเช่นนั้นให้ลองตั้งค่าContent-Dispositionส่วนหัวด้วยค่าinline.

ยังจำได้ว่าเรื่องนี้ก็จะได้รับผลกระทบจากการตั้งค่าเบราว์เซอร์ - เบราว์เซอร์ที่บางคนอาจจะกำหนดให้เสมอดาวน์โหลดไฟล์ PDF หรือเปิดพวกเขาในการประยุกต์ใช้ที่แตกต่างกัน (เช่น Adobe Reader)


ใช่. แต่เมื่อฉันลองทำตามคำแนะนำของคุณฉันได้รับข้อความแจ้งว่า "ไฟล์ไม่ได้ขึ้นต้นด้วย"% PDF- " ฉันใช้ 'Content-Disposition: inline; ชื่อไฟล์ = "the.pdf' ฉันทำผิดพลาดหรือไม่?
dimassony

4
<? php header ('Content-type: application / pdf'); ส่วนหัว ('Content-Disposition: inline; filename = "the.pdf"'); readfile ( '/ dir / เพื่อ / the.pdf'); ?>
dimassony

ดูเหมือนจะไม่ใช่ไฟล์ PDF ที่ถูกต้อง?
Stephen

@Stephen เมื่อฉันเปิดไปที่ไฟล์มันใช้งานได้ แต่เมื่อฉันใช้การแบ่งเนื้อหาแบบอินไลน์มันไม่ได้ผล
dimassony

7
ยินดีรับฟังและยินดีที่ได้ทราบวิธีแก้ปัญหา! จะเป็นการดีถ้าคุณสามารถโพสต์โค้ดสุดท้ายที่แสดงว่าคุณกำลังส่งส่วนหัวใดสำหรับใครก็ตามที่เจอคำถามนี้
Stephen

18
    $url ="https://yourFile.pdf";
    $content = file_get_contents($url);

    header('Content-Type: application/pdf');
    header('Content-Length: ' . strlen($content));
    header('Content-Disposition: inline; filename="YourFileName.pdf"');
    header('Cache-Control: private, max-age=0, must-revalidate');
    header('Pragma: public');
    ini_set('zlib.output_compression','0');

    die($content);

ผ่านการทดสอบและใช้งานได้ดี หากคุณต้องการให้ไฟล์ดาวน์โหลดแทนให้แทนที่

    Content-Disposition: inline

กับ

    Content-Disposition: attachment

เหตุใดคุณจึงปิดการบีบอัด ini_set ( 'zlib.output_compression', '0');
Enigma Plus

เนื่องจากการบีบอัด zlib ไม่ทำงานกับ ob_gzhandler () และนี่เป็นเพียงส่วนย่อยของโค้ดแทนที่จะเป็นสคริปต์แบบเต็ม Ngnix จัดการการบีบอัดได้ดีกว่า php คุณสามารถใช้ zlib ได้หากเหมาะสมกับการตั้งค่าแอปและเซิร์ฟเวอร์ของคุณ
Kareem

4

คุณสามารถปรับเปลี่ยนโปรแกรมแสดง PDF เช่น xpdf หรือเปลี่ยนเป็นการแสดงผลเป็นภาพกราฟิกบนเซิร์ฟเวอร์ของคุณจากนั้นส่งภาพไปยังผู้ใช้ นี่คือวิธีการทำงานของมุมมองไฟล์ PDF อย่างรวดเร็วของ Google โดยจะแสดงผลในเครื่องจากนั้นส่งภาพไปยังผู้ใช้ ไม่มีไฟล์ PDF ที่ดาวน์โหลดมาและแหล่งที่มาก็ถูกบดบังอย่างดี :)


นี่เป็นวิธีเดียวที่ปลอดภัยจริงๆในการป้องกันการขโมยเอกสารต้นฉบับ
Pekka

1
ฉันไม่สนใจเกี่ยวกับการขโมยเอกสารต้นฉบับ มิฉะนั้นฉันต้องการให้ผู้ใช้บันทึกได้ นอกจากนี้ฉันต้องการบล็อกส่วนหัวของไคลเอ็นต์บางส่วน และบางทีฉันอาจจะใช้คำแนะนำของคุณเมื่อผู้ใช้ไม่มี Adobe Reader
dimassony

นอกจากนี้มันจะไม่ใช่การขโมยเพราะต้นฉบับยังอยู่ที่นั่น
Svante

@Svante - ฉันสงสัยว่าเจ้าของทรัพย์สินทางปัญญาจะเห็นด้วยกับตรรกะของคุณ
ashleedawg

@ashleedawg: ฉันสงสัยในชื่อเล่นว่า "ทรัพย์สินทางปัญญา" นี่เป็นเพียงการแฮ็กคำเพื่อทำให้การกักตุนข้อมูลดูเหมือนไม่เพียง แต่เป็นรูปแบบธุรกิจที่ถูกต้องเท่านั้น แต่ยังคุ้มค่าสำหรับสาธารณชนในการป้องกันนวัตกรรม
Svante

1

วิธีที่ปลอดภัยที่สุดในการแสดง PDF แทนการดาวน์โหลดดูเหมือนจะเป็นการฝังโดยใช้องค์ประกอบobjectหรือ iframeนอกจากนี้ยังมีโซลูชันของบุคคลที่สามเช่นโปรแกรมดู PDF ของ Google

ดูวิธีที่ดีที่สุดในการฝัง PDF ใน HTMLสำหรับภาพรวม

นอกจากนี้ยังมีDoPDFซึ่งเป็นโปรแกรมดู PDF ในเบราว์เซอร์ที่ใช้ Java ฉันไม่สามารถพูดถึงคุณภาพของมันได้ แต่มันดูน่าสนใจ


0

นอกจากนี้คุณยังสามารถใช้ระดับ FPDF อยู่ที่: http://www.fpdf.org มีตัวเลือกสำหรับทั้งการส่งออกไปยังไฟล์และการแสดงบนเบราว์เซอร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.