2017-11-23 49 views
8

Tôi có một bản PDF xuất mất một lúc để tạo tệp PDF. Tôi muốn người dùng có thể nhấp vào liên kết xuất và được hiển thị với hộp thoại tải xuống ngay lập tức. Bằng cách này, họ có thể bắt đầu tải xuống và chỉ cần đợi nó hoàn thành. Thay vì nhấp vào liên kết, hãy đợi cho thế hệ và sau đó chờ tải xuống lại.Hộp thoại tải xuống kích hoạt ngay sau khi tiêu đề nhận được

Dưới đây là một ví dụ rất đơn giản trong PHP:

<?php 

header('Content-Type: application/pdf'); 
header('Content-Disposition: attachment; filename=test.pdf'); 
flush(); 

// time consuming PDF creation happens here 
sleep(15); 
echo 'pdf contents would be here'; 

Ý tưởng là để gửi các tiêu đề thích hợp, flush() chúng cho trình duyệt, từ từ tạo PDF và cuối cùng là gửi nó vào trình duyệt.

Điều này hoạt động hoàn hảo trong chrome. Hộp thoại tải xuống bật lên một cách bất ngờ và giấc ngủ là một phần của thời gian chờ tải xuống.

Trong Firefox và InternetExplorer, tính năng này không hoạt động. Các trình duyệt đó chờ 15 giây đầy đủ trước khi hiển thị hộp thoại tải xuống.

Bất kỳ ý tưởng nào làm cho hộp thoại tải xuống bật lên vô tình sẽ được đánh giá cao.

Trả lời

2

Một số trình duyệt chờ nội dung thực tế trước khi hiển thị hộp thoại tải xuống. Vì vậy, giải pháp rất đơn giản: gửi một số nội dung PDF trước khi tạo nội dung PDF.

Đợi một chút. Làm thế nào để bạn gửi một cái gì đó trước khi bạn có nó? Nghe có vẻ như nó sẽ đòi hỏi một cỗ máy thời gian, phải không? Đừng lo lắng, có một cách để vượt qua nó.

PDF content starts with %PDF, do đó bạn chỉ cần gửi %PDF trước khi gọi flush(). Sau khi quá trình tạo PDF hoàn tất, hãy xóa 4 byte đầu tiên của nội dung PDF mới được tạo trước khi lặp lại.

<?php 
// disable output buffering 
while (@ob_end_clean()); 

header('Content-Type: application/pdf'); 
header('Content-Disposition: attachment; filename=test.pdf'); 

// send some content to trigger the download dialog 
echo '%PDF'; 
flush(); 

// time consuming PDF creation happens here 
sleep(15); 
$pdfContent = '%PDF-pdf contents would be here'; 
echo substr($pdfContent, 4); 

Giải pháp này hoạt động bằng bất kỳ ngôn ngữ nào vì nó không dựa trên bất kỳ tính năng chỉ PHP nào.

Nếu bạn muốn làm tối thiểu tuyệt đối, bạn cũng có thể gửi 1 byte % và sau đó chỉ xóa byte đầu tiên trước khi lặp lại. Kết quả tương tự.

+0

Đó là dự đoán của tôi, quá.Tôi đã thử điều này nhưng nó không hoạt động. Để chắc chắn, tôi đã thử lại mã của bạn trong Firefox. Nó vẫn chờ 15 giây trước khi bật hộp thoại tải xuống. –

+0

@AndreasGohr Tôi cho rằng bạn đang sử dụng chỉ 'flush()' bởi vì bạn đã tắt bộ đệm đầu ra của mình. Thực tế là nó không hoạt động có nghĩa là bạn không có. Tôi đã cập nhật mã để làm cho nó hoạt động bất kể cấu hình đệm đầu ra. – Rei

+0

Lạ. Bạn nói đúng, tôi nghĩ rằng tôi đã không có bộ đệm đầu ra được kích hoạt, nhưng với bổ sung của bạn nó hoạt động! Cảm ơn rất nhiều! –

0

Đây là vấn đề chung và không liên quan đến bất kỳ ngôn ngữ cụ thể nào. Chúng tôi đang thực hiện một quy trình để chờ một thời gian cho đến khi tạo Thế hệ PDF và sau đó bắt đầu quá trình tải xuống của chúng tôi.

Vì vậy, để chờ cho Thế hệ PDF, chúng tôi sẽ sử dụng hàm sleep() để cho phép quá trình chờ trong khoảng thời gian cụ thể - 15 như đã đề cập.

sleep(15) 

Bây giờ chúng tôi không thể flush() nội dung trống trước khi pdf được tạo ra cho trình duyệt. Vì vậy, chúng tôi có thể gửi một số nội dung tĩnh trước khi đầu và bắt đầu quá trình tuôn ra của chúng tôi.

Và sau khi tạo PDF thành công, chúng tôi có thể xóa nội dung được thêm trước đó và lặp lại nội dung cập nhật cho hàm flush() của trình duyệt.

Vì vậy, mã tổng thể sẽ là,

<?php 

// Initialize the Basic Header 

ob_start(); // Start Buffering 
header('Content-Type: application/pdf'); 
header('Content-Disposition: attachment; filename=test.pdf'); 

// Adding content before the PDF Generation Process 
echo 'demo'; 

// Flushing content to the Browser 

ob_end_flush(); 
ob_flush(); 
flush(); 

// time consuming PDF creation happens here 
sleep(15); 

$Content = 'demoother pdf content'; 

// Removind the Added Content 
echo substr($Content, 4); 

?> 
+0

"* Vì vậy, để chờ cho thế hệ PDF, chúng tôi sẽ sử dụng một hàm sleep() *". Đó không phải là mục đích của 'sleep()' trong câu hỏi. Thậm chí không gần. Bạn nên đọc lại câu hỏi và hỏi xem bạn vẫn không hiểu. – Rei

Các vấn đề liên quan