views:

583

answers:

3

At first, caching didn't work in all browsers. Then I made it work in all browsers but IE (IE8) by adding .pdf extension to the url. Servlet stopped being called after that.

I display pdf file inline on the webpage via EMBED tag that loads the following url:

http://localhost:7001/app/viewFile.pdf

Which is generated by java servlet with the following headers:

response.addHeader("Content-Disposition", "inline;");
response.setHeader("Cache-control", "cache,max-age=600");
response.setContentType(mimeType);
response.setContentLength(contentLength);

For pdf displaying in all browsers I use Adobe Reader 9.2.0.

How to make it work in IE too? I noticed that IE adds 'Cache-Control: no-cache' header to request, whereas Safari, for example, doesn't.

A: 

Well, one obvious way around the problem is to use URL rewriting. If IE works with .pdf in the extension, use mod_rewrite (Apache) or a similar tool to server-side redirect to the right page, while making the client think that it's indeed requesting a PDF file.

Also: review the HTTP headers that the client is receiving using a tool like Fiddler.

Also: review this older question (http://stackoverflow.com/questions/1597732/php-force-file-download-and-ie-yet-again), I've had similar problems with IE not forcing downloads, too.

Alex
The browser couldn't care less what the extension in the URL is. It's only going to look at the MIME type.
Dolph
They are supposed to look at MIME type but they do not (as I said in the question). Although, I am not sure yet whose fault is that: browser's or adobe reader's.
HappyCoder
+1  A: 

Some ideas to look into:

  1. I don't think cache is a valid Cache-Control directive.

    Try using a value of public instead, or private if that's more appropriate to your content. Check out RFC 2616 for more information.

  2. Perhaps you're sending more than one Cache-Control directive?

    Use a tool like Firebug or LiveHTTPHeaders to peek at the actual headers your browsers are receiving. Make sure they're not getting something you don't expect. It sounds like you might already be doing this though. Also make sure you're not also sending Pragma: no-cache.

  3. Try setting the Expires header in addition to using Cache-Control.

    It's also possible you're sending the browser conflicting Cache-Control/Pragma headers and IE chooses to take the Pragma headers as first priority for whatever backwards reason.

  4. Make sure IE is configured to allow caching! :)

    Control Panel > Internet Options > Temporary Internet Files > Settings > Check for newer versions of stored pages

  5. Try sending the PDF as a response to a POST request (via form submit).

    IE is allowing a cache to take place regardless of the headers in the response due to this requirement from RFC 2616: "By default, a response is cacheable if the requirements of the request method, request header fields, and the response status indicate that it is cacheable." Responses to POST requests are NOT cacheable, so IE shouldn't include that header in it's request.

  6. Try sending the Content-MD5 and Last-Modified headers with consistent values (if they're not already being sent).

    This might help convince IE that the content of the PDF has not changed. I don't think this solution will work, because IE is obviously stubborn, but it's worth mentioning.

Dolph
Funny thing is that when I set "Never" at "Check for newer versions of stored pages", IE still gets a new version of pdf :S
HappyCoder
I added two more suggestions (5 and 6). I think the 5th one is your best bet.
Dolph
+1  A: 

As said before, the cache-control header value cache is invalid. Use public instead.

As to IE not adhering the server-side cache control rules in the embed and object elements, this is unfortunately a "feature" of IE. Best what you can do is replacing it by an iframe element.

Other headers like expires, last-modified, etag and so on ain't going to help.

BalusC
Any link with details?I tried iframe too long time ago but it didn't help. I will try it today again.
HappyCoder
Maybe because you used the wrong header.
BalusC
Cache-control: public,max-age=600Pragma: public,max-age=600Moreover, other browsers (tried Safari) stop caching the pdf when it's in iframe.
HappyCoder
Interesting, I created a test case with `iframe` and a `cache-control` of `public,max-age=600` on the header of the PDF file and it works in FF/IE/Chrome/Opera, but indeed fails in Safari.
BalusC
IE is unfortunately unpredictable.
BalusC
I tried again and it worked. You were right! With iframe, IE sends a different request where "Accept" is different and there is no no-cache in this request :) One problems left -- Safari.
HappyCoder
I create iframe/embed via js now. For Safari, embed is displayed. In IE8 have to do jQuery('iframe.pdfViewer').remove(); Otherwise, white area remains on the page (ajax is on).
HappyCoder
In Windows however, Safari is not caching pdf even via embed tag :S Damn, this problem is so annoying!
HappyCoder