3
votes

I am running Windows 7, 64 bit. I have recently updated my OS to install the latest updates. Since then, most PDF documents have stopped rendering in my program. My program wants to display PDF documents in a separate iFrame. I do this by getting the URL of the PDF document and setting window.frames['docview'].location = url; In most cases, the iframe view remains blank (or clears if something was shown there previously). If I take that same URL and open it in a new tab or window, it renders fine.

When it fails to render in my iframe, I see the following message in the Chrome console:

Resource interpreted as Document but transferred with MIME type application/pdf.

Firefox does not offer a message of any kind in its error console, or on the FireBug console.

I have no control over the source of the PDF files, so I cannot change their header information.

Oddly, some files do load correctly.

Looking at the network requests in Chrome, for a document that fails to load I see (for example):

Request URL:http://es.csiro.au/pubs/paradis_mdm03.pdf
Request Method:GET
Status Code:200 OK

Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:es.csiro.au
Referer:http://querium.fxpal.net:8080/querium/ui/query?searcherId=2&compact=true&sidx=rank&topicId=2&queryId=1&lastEventId=1490893682130103&highlight=undefined
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1

Response Headers
Accept-Ranges:bytes
Connection:Keep-Alive
Content-Length:71764
Content-Type:application/pdf
Date:Tue, 06 Sep 2011 04:59:26 GMT
ETag:"1f48c8-11854-43e4ee482ef40"
Keep-Alive:timeout=15, max=100
Last-Modified:Wed, 07 Nov 2007 04:07:49 GMT
Server:Apache/2.0.55 (Ubuntu) PHP/5.1.2 mod_ssl/2.0.55 OpenSSL/0.9.8a

When opened from a separate tab (where the document does render), I get the following:

Request URL:http://es.csiro.au/pubs/paradis_mdm03.pdf
Request Method:GET
Status Code:304 Not Modified

Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:es.csiro.au
If-Modified-Since:Wed, 07 Nov 2007 04:07:49 GMT
If-None-Match:"1f48c8-11854-43e4ee482ef40"
Range:bytes=0-71763
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1

Response Headers
Connection:Keep-Alive
Date:Tue, 06 Sep 2011 05:07:15 GMT
ETag:"1f48c8-11854-43e4ee482ef40"
Keep-Alive:timeout=15, max=100
Server:Apache/2.0.55 (Ubuntu) PHP/5.1.2 mod_ssl/2.0.55 OpenSSL/0.9.8a

One odd things is the difference in status, but maybe the server is being smart or there is some funny interaction with the cache. Who knows.

Any help would be greatly appreciated.

Gene

EDITED: 9/6/2011

When I removed the tag

 <meta http-equiv="content-type" content="text/html; charset=UTF-8">

from the <head> element of my HTML page, many (but not all) of the PDFs started rendering properly. This was an apparent duplicate of another meta tag in the header:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

Does this help shed any light on the potential problem?

2

2 Answers

2
votes

Instead of setting the src attribute of the iframe to the PDF, set it to a wrapper HTML-file, which contains a simple div:

<!DOCTYPE html>
<html style="height:100%;">
<head>
</head>
<body style="height:100%;">
    <div id="divContents" style="height:100%;"></div>
</body>
</html>

In javascript the contents of the div is set to an object element. Unfortunately slightly different versions are needed to work reliable on all browsers (tested on IE, Firefox and Chrome):

(I simplified the retrieval of the divContents element and the browser detection)

var embed = '<object type="application/pdf" width="100%" height="100%"';
if (msie) {
    embed += '><param name="src" value="' + pdf + '"/>';
}
else if (chrome) {
    embed += ' src="' + pdf + '">';
}
else {
    embed += ' data="' + pdf + '">';
}
embed += '</object>';
$("#divContents").html(embed);

UPDATED

I've finally found the actual cause of the failure in Chrome: It's the Accept-Ranges:bytes field, without it Chrome will not work when the data attribute is used.

  • So if your server is capable of supporting the Accept-Ranges field, you should make sure it is returned to the client. In that case you can use the pdfobject library to display the PDF in a frame or div.
  • If not, you can use the code above to display the PDF in a frame or div.
0
votes

In the past a few issues has been reported with pdf loaded in iframes, both for Firefox and Chrome (in particular when headers like Content-Type and Content-Disposition are not properly set).

Probably you should use an <object> tag to embed a pdf in your page, instead of an iframe, but an easier solution is the pdfobject library. To verify this works, you can browse this jsfiddle with Chrome and Firefox.

Moreover, you can use a proxy script in your server to stream the PDFs: your page will point to the proxy script and pass an identifier (so that it won't be hacked easily) and the script will download and send to the browser the matching pdf with the proper headers.

Finally a note about the different status codes: in the first response the server has sent to the browser the Last-Modified and the ETag that contains a timestamp and a hash of the file; thus the browser, in the second request ask for the resourse only

If-Modified-Since:Wed, 07 Nov 2007 04:07:49 GMT
If-None-Match:"1f48c8-11854-43e4ee482ef40" 

Since the resource has not be changed, the second response is a 304.