Reputation: 305
I have a problem with reading pdf file in Chrome by using PHP.
The following code is how I do in PHP
$path = "actually file path";
header("Pragma: public");
header("Expires: 0");
header("Content-type: $content_type");
header('Cache-Control: private', FALSE);
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Disposition: inline; filename=\"$filename\"");
header('Content-Transfer-Encoding: binary');
header('Content-Length' . filesize($path));
ob_clean();
flush();
readfile($path);
In here, I set the Content-Disposition to inline. Because I want to display the pdf file if user browser have build-in pdf viewer plugin. As you may know, Chrome has build-in pdf viewer.
The problem is I have bunch of pdf files on the server. Only some of them can be viewed by Chrome. I can't figure out why others can not work the same way. I have checked the permission of each files. It looks like not the permission problem.
Is there anyone know what the problem is? Thank you.
Upvotes: 8
Views: 64910
Reputation: 13
Been through this issue myself. Fixed the header code, but please also note that the integrated pdf viewer of Chrome also WILL fail if you are loading the pdf inline from a url with username and password in it i.e. "http://**username:password@**domain.com/pdf_dump.php". If you are able to first redirect to a url without username and password, it will solve the problem.
Upvotes: 0
Reputation: 66
None of the solutions above worked for me, but the bellow code works. All you need to do is to send the file by chunk.
$fileSize = filesize($filePath);
header("Expires: 0");
header("Content-Type: application/pdf");
header("Content-Description: File Transfer");
header('Content-Disposition: inline; filename="' . $yourFileName.pdf . '"');
header("Cache-Control: private, max-age=0, must-revalidate");
header("Content-Length: $fileSize");
header("Accept-Ranges: bytes");
//Flush the output buffer immediately
//The following three lines is important. Without them, it will not load large files:
ob_end_flush();
ob_flush();
flush();
$handle = fopen($filePath, "r");
$chunkSize = 2024 * 2024; // 1MB (Adjust as needed)
while (!feof($handle)) {
echo fread($handle, $chunkSize);
ob_flush();
flush();
}
fclose($handle);
exit();
Upvotes: 1
Reputation: 436
I was having this issue, struggled for almost 6 hours and finally got it working. My solution is similar to the above answers but the above answers are not completed. There are three steps to solve this issue.
Step 1. Go to php.ini file and add this line.
output_buffering = False
Step 2. This error comes if you are opening a large PDF file. So, to solve this, just before adding headers, make sure you put these two lines.
set_time_limit(0);
ini_set('memory_limit', '100M'); //the memory limit can be more or less depending on your file
Step 3. Add below headers and the code to read the file, so the final code would like this.
set_time_limit(0);
ini_set('memory_limit', '100M');
$file = "path/to/file.pdf";
header('Content-Type: application/pdf');
header('Content-Disposition: inline;
filename="yourfilename.pdf"'); //not the path but just the name
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file));
header('Accept-Ranges: bytes');
header('Expires: 0');
header('Cache-Control: public, must-revalidate, max-age=0');
ob_clean();
flush();
readfile($file);
exit();
100% working solution. If you have any issues, let me know :)
Upvotes: 0
Reputation: 6581
After hours wasted this...i added comments to point out that @Kal has the only solution that worked. But somehow that's not enough...this is such an impossible and frustrating problem when Chrome does this:
Error Failed to load PDF document. Reload
Here is the diff that ended the torture.
- // Waste time with chrome:
- header("Content-type:application/pdf");
- header("Content-Disposition:attachment;filename=$file_basename");
- readfile($file);
exit();
---------------------------
+ // Deliver the file:
+ header('Pragma: public');
+ header('Expires: 0');
+ header('Content-Type: $mime');
+ header('Content-Description: File Transfer');
+ header('Content-Disposition: attachment; filename="'.basename($file).'"');
+ header('Content-Transfer-Encoding: binary');
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+ header('Content-Length'.filesize($file));
+ ob_clean();
+ flush();
+ readfile($file);
exit();
For about thirty minutes i fooled with various variations of this...but i could not pin it down to "Add HTTP 200", not to "add bytes", not to "quote your filename", not to "separate the file ending". None of those worked.
(Thank you again @Kal).
Upvotes: 0
Reputation: 59
For me adding the following header fixed this annoying Chrome bug (?):
header('HTTP/1.1 200 OK');
Upvotes: 4
Reputation: 11
Had the same problem, chrome didn't display the inline PDF, stuck at loading. The solution was to add header('Accept-Ranges: bytes')
.
My complete code:
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="'.$title.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file));
header('Accept-Ranges: bytes');
header('Expires: 0');
header('Cache-Control: public, must-revalidate, max-age=0');
Upvotes: 1
Reputation: 11
i've fixed this way
$path = 'path to PDF file';
header("Content-Length: " . filesize ( $path ) );
header("Content-type: application/pdf");
header("Content-disposition: inline; filename=".basename($path));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
ob_clean();
flush();
readfile($path);
Upvotes: 1
Reputation: 988
I had similar issue but I noticed the order matters. Seems that ; filename=
must have quotes around it, Content-Disposition: attachment
Try this:
$file = "/files/test.pdf";
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
$mime = finfo_file($finfo, $file);
header('Pragma: public');
header('Expires: 0');
header('Content-Type: $mime');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="'.basename($file).'"'));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Length' . filesize($file));
ob_clean();
flush();
readfile($file);
Upvotes: 1
Reputation: 294
I've been wrestling with this same issue. This is as close as I got to consistent results across browsers. I think that the reason you could be having problems is if some PDF's are too large for readfile() to handle correctly. Try this:
$file = "path_to_file";
$fp = fopen($file, "r") ;
header("Cache-Control: maxage=1");
header("Pragma: public");
header("Content-type: application/pdf");
header("Content-Disposition: inline; filename=".$myFileName."");
header("Content-Description: PHP Generated Data");
header("Content-Transfer-Encoding: binary");
header('Content-Length:' . filesize($file));
ob_clean();
flush();
while (!feof($fp)) {
$buff = fread($fp, 1024);
print $buff;
}
exit;
Upvotes: 12