PDF redirection shows blank on Chrome - php

I'm having this issue that I can't solve for the life of me.
I have a simple php script that redirects to pdfs, the code is as follows:
$file = "url/to/file";
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Description: File Transfer");
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="somefile.pdf"');
header('Content-Transfer-Encoding: binary');
readfile($file);
exit();
If I try it directly in a browser tab, it works, it connects with Chrome's pdf plugin and shows it to me. If I try to put this on a link on another page, or try to open it via window.open in javascript, It shows a blank page. This only happens in Chrome and Safari, Firefox and Edge show it fine. Before anyone asks, I've tried it with and without the cache and content-description headers, which I've got from answers I found here, this is just the last version I have.
Any ideas?
Thanks in advance
EDIT
I forgot to mention that the problem persists on the blank tab even if I reload the page. I've checked the Network tab on devtools, they show identical results for bot requests and responses (the redirect and the direct one) but the redirect doesn't work. Also, no errors of any kind on either one.
Also, I've tried it without the exit(), doesn't change a thing.

As mentioned in the comments by ylva, for anyone searching for this, the answer can be found here
Open PDF from Chrome IFRAME failed with default PDF viewer
Main thing is, Chrome's PDF viewer embeds the PDF as an application, so if the link to a PDF file comes from an iframe, and this iframe has the sandbox attribute, chrome won't let it run, you either have to remove the sandbox attribute or have to install your own PDF viewer. So it had nothing to do with the PHP code itself.
Cheers

Related

"Network failure" to download PDF generated with with PHP FPDF/FPDF2File class in Google Chrome

I have reports generated in PHP / FPDF / FPDF2File that are usually displayed in the browser window.
Notice:
The parameters are passed to the PHP that generates report POST.
The file is being accessed exclusively via HTTPS with a valid certificate.
The web server is able to log all errors and errors are being properly recorded in the log, but no error related to that FPDF/PHP is being recorded. (Ie I clean the error log, run the report and no error appears in the log ... forcing a mistake on purpose and it is registered). Thus, it seems that there is no syntax error.
The Content-type used is: header ( 'Content-type: application / pdf');
The problem occurs in Windows computers with Google Chrome (tested on multiple machines).
All buttons of the PDF rendering plug-in browsers (save, print, rotate, zoom, etc.) work normally. Except the save button in Google Chrome (in other browsers work normal).
When trying to save the PDF already opened and displayed on Google Chrome, the following error occurs:
Failure - Network error
Therefore, you can not save the PDF, unless you go to print and print in PDF, or print the PDF PDF, which does not make much sense.
Could someone tell how to solve this error?
Thanks a lot!
Do you set the no-store property of the Cache-Control header?
I don't know why, but for me it worked after changing
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
to
header("Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0");
#Amryn's answer actually worked for me. Here's my full header setup:
header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="relatorio-clientes.pdf"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . strlen(ltrim($content)));
header('Accept-Ranges: ' . strlen(ltrim($content)));
echo $content;
If you use the Print option and Save as PDF, network error does not occur (workaround).
That's works for me :
Remove all characters like space after the php close tag ?>
Found here :
https://stackoverflow.com/a/13463631/2267379
Simple solution: Don't do a
return $pdf->Output('medienpass.pdf', 'D');
in your getPdf() function because the output will be wrapped up in a
lot of html code.
Instead return only your pdf to the client:
die($pdf->Output('medienpass.pdf', 'D'));

.xls file generated with PHP will save but not open from IE

I am using PHP to dynamically generate a table which the user can download as a .xls file. When the using IE, after clicking the link, the "Do you want to open or save the file..." dialog pops up. If the user saves the file and opens it, there is no problem. But if the user chooses 'Open', Excel launches, but it is empty. There is no spreadsheet. Everything works fine in Chrome and FF.
Here is the code I'm using.
<?PHP
// filename for download
$filename = "filename" . date('M_j_Y') . ".xls";
//create the output
$output = //<table> code goes here.
//set the header to treat this as an excel file
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
echo $output;
exit;
?>
This is what happens when I click the link to download the spreadsheet and then choose 'Open' from the IE10 dialog.
Any advice on how to make the spreadsheet open when an IE user clicks 'Open' would be greatly appreciated. Thanks.
you can try this:
a. Right click on the file and choose Properties
b. On the General tab, click Unblock
c. Click OK
Check this link: https://support.microsoft.com/en-us/kb/3181507
Microsoft's documentation suggests that the issue may actually be a setting in Excel -- that Excel may be ignoring Dynamic Data Exchange (DDE) information from IE. Might check the setting described and see if that's it.

Force image download with php using header() in smartphones and tablets

I was searching already for a long time and I havent seen any right answer yet.
I'm trying to create a system in PHP where the user can download a signPicture that I create in JPG.
The program is working fine in all desktop computers. There is not problem at all, even for IE8.
The header that I use:
header("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename="test.jpg"');
in the end i just stream the picture:
imagejpeg($imgSign,NULL,100);
How I said, it's working really good in every browser. But then we get to the mobile devices, where in android for example, download a test.jpg file... but then it cannot open... and the same with ipad (actually doesnt download, it show the image in the browser and than I save it... but it does not open either).
I also try more examples that I saw, but doesnt change anything, like:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/download");
header("Content-Transfer-Encoding: binary ");
Any idea how to sort this out in mobile devices?
Thanks!
I got it!
There were differents problems. I found the clear solution in comments from this post:
http://www.digiblog.de/2011/04/android-and-the-download-file-headers/
header("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename="test.JPG"');
The important steps: I send everything with a form. The form, to make it work in mobiles, needs to have the target='_top' and the method='get'
It also make errors if the extention (jpg) is not in UPPERCASE and the file name is not between " ".
Now it works in all devices that I try by far. :)
Special thanks to Jörg Wagner, author of the post.

Protecting / serving a file via readfile(), force download?

I'm trying to make a simple script that does two things:
Serves up a file and hide's it's destination
Has a download counter
Now, I'm doing this in the wordpress environment, but this question isn't completely wordpress-related so I figured I would ask here.
Basically, the way I have it set up, currently, is I have a link that when you click it sets a $_['GET'] which is then checked if is set. If it is set, the download file is served.
the link: Click here!'
the $_['GET'] code: http://pastebin.com/93nD43gA
There is a bit of wordpress jargon in the code, but basically it's checking a download count user_meta and if it's > 0, serveFile() is called.
The main problem I'm having here is, if I click the link, readfile() loads the actual file contents INTO the window (garbled text). If I add a target=_blank to the <a> it opens a new browser window and loads the contents INTO the window.
This approach seemed to work perfectly fine when I was doing it as stand-alone php files. My main issue is that I need to keep the wordpress space so I can call functions, etc. associated with it.
I have tried using the $_['GET'] on both the self page, another page with a custom template (the code in the pastebin above), and as a stand-alone php file. Both the first two options load the file INTO the window. The third doesn't preserve wordpress functions, even if I include blog-header.php.
Can anyone point me in to the right direction of how to get the file to force download and not load INTO the window?
You need to set the appropriate header for whatever the file type is. For example, if readfile always serves, PDFs, it should be done like this:
// disable browser caching -- the server may be doing this on its own
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Type: application/pdf');
//forces a download
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=filename.pdf');
readfile($file);
Keep in mind that header only works if you have not sent any data in the request at all including whitespace.
The 'garbled' text is what you want however besides that you have to set a mime. This can be accomplished by simply setting a header, e.g. header("Content-Type: image/png");
If the file mimes will vary (e.g. pdf, doc, png, etc) you should look into finfo extension. With it you can get the full and correct mime of the file
<?php
$finfo = new \finfo(FILEINFO_MIME);
$mime = $finfo->file('path/to/file', FILEINFO_MIME_TYPE);
header("Content-Type: $mime");
As noted - headers can be set only if no write to output has been done (no echo's, print, etc. Output buffering could help you here).

Problems with header() when displaying a PDF file in IE8

So, I have a file that sends the following:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: private");
header("Content-type: application/pdf");
header("Content-disposition: inline; filename=file.pdf");
header("Content-length: 7735");
then I echo out the file - it is a PDF file.
Works fine in IE6 & 7 on XP (and FF for that matter)
The very same code shows nothing when running on IE8 on either XP or Vista.
There are no security warnings, etc so I don't think it has to do with that.
And, if my memory serves me correctly, this worked on IE8 a while ago.
What am I doing wrong here? Am I missing something out of the headers?
Is there a way for me to see what header information normal comes over when viewing a PDF in IE8 so I know what to emulate?
After looking at things it still works in IE8 EXCEPT when SSL is on
Under HTTPS and IE8, those headers fix the download problem:
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: public");
Other X-something headers did not make any difference.
It has probably to do do with the SSL. I read this article (in German, with code examples) where the author set the following header:
header('Pragma: anytextexeptno-cache', true);
I'm not sure what is needed, but here is what you could do.
Put the file temporarily in a public place on your server, make syre you can download that with a direct link in IE8, Use firefox LiveHTTP headers or similar to grab all headers that the server sends. Spit them out in exactly the same way and order in your script. (And don't forget to delete the file).
Something I want to add, as I faced this problem, too, in a slightly different way using Joomla.
Normal PDF-Output of content worked fine, in all browsers.
But the generation of a pdf from within my own component (using JDocument, tho) generated the bevahiour mentioned above.
My solution: Explicitly enable caching for my component using the following statement in view.html.php:
JResponse::allowCache(true);
Maybe that helps somebody.
I'm using HTTPS and i had some problems, but using those headers the download did.
Try it.
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: public");
header("X-Download-Options: noopen "); // For IE8
header("X-Content-Type-Options: nosniff"); // For IE8
header("Content-type: application/pdf");
header("Content-disposition: inline; filename=file.pdf");
header("Content-length: 7735");
The problem is you cant direct open. Just save.
Possibly related: Can't display PDF from HTTPS in IE 8 (on 64-bit Vista)

Categories