Sunday, May 22, 2011

PHP PDF generating over HTTPS issue on IE6 with blank page returned [REALLY SOVLED]

This is really a typical question raised at all time about mysterious IE6 PDF opening issue over HTTPS connection:


How can we successfully output PDF dynamically via HTTPS connection on various browser including IE6?


Whatever server-side language you use, you may encounter this yourself once or more in your life. As people trying to find a definite reason for this, it seems to be more than one anyway.


Say, using PHP, people encourage to add appropriate headers to make PDF stream opening on the fly directly in IE6 browser.



//size_of_stream is counted by bytes
//Display pdf text stream direct on the browser (IE bug fixed!)
//by setting the content-type


header("HTTP/1.1 200 OK");
header("Status: 200 OK");
header("Accept-Ranges: bytes");
header("Connection: Keep-Alive");


//Comment out for debugging purposes
//header("Cache-Control: public");
//Try setting 1 delta second for caching long enough for Adobe Addon to load PDF content
header("Cache-Control: public, max-age=1");
//Only need to specify User-Agent in Vary header as IE7 only accept that
//Default Vary header value is not welcomed at all
//Fixing IE7 bug for Vary header
header("Vary: User-Agent");
header('Pragma: public');
if (!is_null($size_of_stream)){header("Content-Length: ". $size_of_stream);}
header("Content-Type: application/pdf");
header('Content-Disposition: inline; filename="whatever.pdf"');
header("Content-Transfer-Encoding: binary\n");


This is almost true in many cases, including all the popular browsers like Firefox, Safari and Chrome. Yet there is still exception that PDF may not open properly on IE6, especially for small sized PDF stream.


Searching around for any server-side solution, it was really disappointed in terms of support of Internet Explorer 6.


Finally, I have a glimpse on a comment posted in the other forum which seems to work on almost any case with major version of Internet Explorer:


In Internet Explorer

  1. Select Tools
  2. Click Internet Options
  3. Select the Advanced tab
  4. Make sure "Do not save encrypted pages to disk" option near the bottom in the Security section is unchecked
This implies there is hardly any programming way to ensure PDF opening perfectly working.

Option "Do not save encrypted pages to disk" should only be enabled by default on Windows Server, whereas on most desktop PC the followings should be applied for security reason:


  1. Go to the Tools menu
  2. Click Internet Options
  3. Click the Advanced tab
  4. In the "Settings" box, scroll down to the section labeled "Security" 
  5. click to check the box next to the "Empty Temporary Internet Files folder when browser is closed" option
  6. Click OK to finish



This option does not delete cookies, but it will clear your cache of other files when you close your browser.

Now, the thing is how we are going to let people in an organization to follow this. This makes me unhappy:(




Related links:


http://joseph.randomnetworks.com/2004/10/01/making-ie-accept-file-downloads/#comment-670


http://robm.fastmail.fm/articles/iecachecontrol.html




However, this is not the end of the story.


To be enthusiastic for my work and diligent regarding all these, I keep digging deep into what's happening on a scenario which I have met in producing PDF on the fly.


For IE6, part of my PDF streams can be displayed correctly regardless of what option "Do not save encrypted pages to disk" disabled or not. When I tried to check the size of a successful PDF generated on the fly, they all show a bigger size like 120KB, 80KB or 76KB.


I did find some developer posts about the problem regarding PDF stream size to be displayed on IE. As I didn't remember wrong, someone mentioned about 8 Kilobytes in size to be minimum requirement on IE6.


When I go back to check that problematic PDF file by Firefox, it shows a size of 4 Kilobytes. Well, it's time to do an experiment on this.


Using PHP, it is easy to echo PDF stream first. Then you can calculate the size of stream by using function like strlen() to check size of string. Multiply this length by 1024, you'll get Kilobyte size yourself.


$len = strlen($pdf_stream)*1024; //length in bytes


Using simple algorithm to check it the length if it is less than 8192 bytes or not. When this is the case, you can first echo the PDF stream first.


echo $pdf_stream;


Then padding the spaces in advance:


for ($v=0;$v<=8192;$v++){
   echo ' '; //output space character
}


This makes sure the actual PDF output plus extra padding spaces occupying at least 8KB in size for IE compatibility.


Now, the problem is really solved across the browsers:)



No comments:

Post a Comment