this is my first question to the community, although I usually find all the answers I need on the forum, I had no luck on this one.
The problem is I have a php script witch outputs an inline pdf like so:
$doc = base64_decode( $rapport );
header('Content-type: application/pdf');
header("Content-Disposition: inline; filename='rapport.pdf'");
echo $doc;
But it only works when i open the page as an admin on my wordpress site.
If another user opens it, the Content-type header just get ignored ... but i can see the bytes of the doc.
I tested myself by opening the same page in the same browser logged in as another user and the header I see in chrome dev-tool is Text while it is application/pdf normally.
Any help would be appreciated.
Thx!
Edit: Problem half solved, the wp super cache plugin was compressing the output so everything works fine again without the cache... Any suggestions as how I should set the cache plugin to avoid breaking the dynamic content?
Related
I'm outputting a PDF via PHP with the following code. $file is an object that contains data pertaining to the file being displayed.
header('Content-type: application/pdf');
header('Content-disposition: inline; filename="'.$file->name.'"');
#readfile($file->ServerPath());
My issue is that when I go to download the file in Chrome it will occasionally try to save the page instead of the PDF.
For example, say the URL that is displaying the file is mywebsite.com/file?file_id=1234. Most of the time it will try to save the file correctly as "file_name.pdf". However, sometimes chrome will try to save the file as "file" with no extension. This seems to happen randomly.
If it makes any difference the page displaying the file is being opened in a new tab. The issue happens regardless of whether I redirect via PHP or Javascript.
I really need to resolve this issue, as these PDFs will be accessible by users.
Thanks in advance.
When generating a PDF in the browser programmatically (via PHP) the rendered PDF displays fine in both Firefox and Safari, but Chrome returns an ERR_INVALID_RESPONSE. It is a valid PDF - can be opened locally with Adobe Reader/Preview once saved from the working browsers, and will even open in Chrome once the PDF is saved from a different browser.
The PDF file is being read through file_get_contents(), is given a current timestamp and then passed to the browser. A workaround would involve saving the file to a temporary spot and redirecting the user (for Chrome, at least) but this is not ideal.
I've researched it and only been able to find bug reports dating from 2008.
I have an inkling it's a header error. After the PDF is generated, the following headers are sent to the browser (again working fine in FF, Safari and IE):
header('Content-type:application/pdf');
header("HTTP/1.1 200 OK");
I've also tried adding the following headers after searching on Stack Overflow, but to no avail:
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
Are there missing headers that Chrome requires? Does anyone have experience with getting dynamically generated PDFs to display in Chrome?
EDIT: One of my more salient questions is what could be causing this to work fine locally in Chrome, but wouldn't work on a server environment.
In my case I had to add these 2 parameters to headers because wordpress was sending 404 code as it didn't recognize the url of my php function:
header("Content-type: application/pdf",true,200);
as stated in this answer on wordpress.stackexchange.
This forces the headers to replace (2nd param true) the 404 status code generated by wordpress as it does not recognize the custom url, and sets 200 OK (3rd param 200).
So it ended being something like this:
$pdf_name = "test.pdf";
$pdf_file = "/absolute/path/to/my/pdfs/on/my/server/{$pdf_name}";
header('Content-type: application/pdf',true,200);
header("Content-Disposition: attachment; filename={$pdf_name}");
header('Cache-Control: public');
readfile($pdf_file);
exit();
Try this
<?php
$filename = 'Physical Path to PDf file.pdf';
$content = file_get_contents($filename);
header("Content-type:application/pdf");
// It will be called downloaded.pdf
header("Content-Disposition:inline;filename='".basename($filename)."'");
header('Content-Length: '.strlen( $content ));
// The PDF source is in original.pdf
readfile($filename);
?>
<html>
<body>
...
...
...
Make sure that above header code is called before output of PHP script is
sent to browser.
I want to thank everyone for their answers.
It turns out this was not related to the headers. After attempting to change/remove headers in various ways (detecting encoding, trying with and without content-length, etc.) we decided to dig into the deeper httpd logs to see if anything was resolving differently for Chrome.
It turns out that mod_sec on our server was flagging the request (only from Chrome for some reason) as an attempt at a file injection attack and was returning a 403 forbidden response. Chrome displayed this as the ERR_INVALID_RESPONSE rather than a 403.
The hostname of the CDN was present in the request (we had ample checking at the endpoint to ensure that the file was indeed an allowed resource), and instead are building the URL out on the server instead.
are there any standard way to make something similar?? I just want a way to download xml files from the server. Please help me!
No, as to my knowledge there is no way to do this using HTML.
You have to fix it on the target page. If a certain HTTP header is sent, the browser will offer a page for download instead of displaying it. This should work in every major browser. The necessary header is Content-Type: octet-stream. How you send this depends on your setup.
You can always send it by configuring your web server to do so, but how exacly depends on which web server you are using.
If, on the other hand, your XML file is generated by a PHP script, it's easy. Just add the following line before anything else is written, so preferably to the top of said script:
header('Content-Type: application/octet-stream');
If it's a static XML file... well, you could make a "proxy file" for that. Add a PHP file with the following content:
<?php
header('Content-Type: application/octet-stream');
// This "fakes" the file name, so the downloaded file isn't called
// "download_xml_file.php" or whatever you name the script.
header('Content-Disposition: attachment; filename=my_xml_file.xml');
readfile('path_to_the_actual_xml_file.xml');
?>
But try to avoid this hack. It's unnecessary bloat and it will break browser caching.
navigator.msSaveBlob(blob, filename)
https://msdn.microsoft.com/sv-se/library/windows/apps/hh772331
Unfortunately I don't know a way to do it in Safari.
Here you have a table with the browsers and thier compatibility with attribute download that Mike posted you in a comment: http://caniuse.com/download
And the actual tag with attribute is (just for sure you typing it right):
<a href="your_path_to_file" download>Download Me!</a>
-- it will work only in firefox, chrome and opera as it is in a table.
The download attribute only works in Firefox and Chrome. It will not work with IE, safari or Opera.
My intention is to convert a total php page into html, and subsequently convert the html to pdf and render it through the browser.Which is done , apart from that while showing it on the browser , it will simultaneously download the pdf automatically which is not happening.
Its with PHP.
Can to tell me the basic concept ..as to how to do this.
Thanks in advance
You already render the page in the browser. Before displaying the page, header() the user to the location which will serve the same page as an attachment, but do not exit. This will allow them to download the file, but it will still load the file on the page. Not 100% sure that this will work, but it's worth a shot.
BTW different browsers will handle pdfs differently and depending on settings, plugins, etc. For instance, some might try to download the file anyway instead of showing it in the browser.
I think you need to look over the question again. As I read it, you're asking how to display something that hasn't yet been downloaded (while it's downloading), and that is obviously not possible and so cannot be what you mean.
Try creating a header, which tells the browser what to do when it receives the file.
<?php
header("Content-Type: $filedatatype" );
header("Content-Disposition: attachment; filename=\"" . $FileObject->name . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $filesize);
?>
Today I started experimenting with PHP-based PDF generators. I tried TCPDF and it works fine for the most part, although it seems to be a little slow. But when I load the PHP file that generates my PDF in Internet Explorer 8, I see lines and lines of weird characters. Chrome however recognizes it as a PDF.
I'm assuming that I have to set a special MIME type to tell IE that it should interpret the page output as a PDF file. If yes, how can I do this?
putting "application/pdf" or "application/octet-stream" mime types might help. keep in mind that "application/octet-stream" will force download of the file and might prevent it from opening in the browser..
in case you wonder, you can do it like that:
header('Content-type: application/octet-stream');
I had this problem also but what I did to get it work is I added
exit();
at the end of pdf output.
You need to handle IE differently for dynamic-generated content. See this article,
http://support.microsoft.com/default.aspx?scid=kb;en-us;293792
In my code, I do this,
if(isset($_SERVER['HTTP_USER_AGENT']) AND ($_SERVER['HTTP_USER_AGENT']=='contype')) {
header('Content-Type: application/pdf');
exit;
}
This problem may also explain slowness you mentioned because your page actually sends the whole PDF multiple times without this logic.
#Pieter: I was experiencing the same issue using tcpdf (with fpdi), and loading the page that was generating the pdf using an ajax call. I changed the javascript to load the page using window.location instead, and the issue went away and the performance was much better. I believe that the other two posters are correct in the idea that the document header is causing the issue. In my case, because of the ajax call, the header was not being applied to the whole document, and causing the issue. Hope this helps.
I found this to be a problem too, and for me this all hinged on the code:
if (php_sapi_name( != 'cli') {
on line 7249 of the tcpdf.php file.
I commented this 'if' statement (and related '}')and all works fine for my other browser and ie8
Hope this helps