9

Is it possible to disable caching at an item level in the media library? We have specific PDF files that are updated every week, but it's simply not feasible to create a new item in the media library and update all of the links from the old item to the new one. The main issue is that we have client side caching on, so regardless of what happens server side, the client still needs to shift+f5 (or equivilant) in order to see the updated PDF file. Is there a way we can disable this caching for our specific PDF's?

The next steps would probably involve patching into the media library item url resolver process, and see if we can tack on the last updated date as a querystring parameter. It's a hacky workaround that I'd like to avoid if possible.

1 Answer 1

9

I would recommend solving this by embracing HTTP caching by changing the Cache-Control to no-cache. The browser will then always check to see if there's a newer/different version but since media items have Etag headers, the browser won't download the data it again if it's the same version it has cached.

As for implementation, you can apply this to all media items by setting the MediaResponse.Cacheability Sitecore setting to serverandnocache. However I that would also put more load on your server since all images would also be uncached. To avoid that, you'll need to subclass MediaRequestHandler and override SendMediaHeaders:

protected override void SendMediaHeaders(Media media, HttpContext context)
{
    base.SendMediaHeaders(media, context);

    if (media.MimeType == "application/pdf") // Preferably a more specific descriminator
    {
        context.Response.Cache.AppendCacheExtension("no-cache");
    }
}

Now for the detail.

In HTTP, the Cache-Control response header tells the browser how to cache the request. Cache-Control: private, max-age=600 indicates that the response can be cached by the browser for 600 seconds.

After this time, the resource will be re-requested from the server. However, if identity information (Etag or Last-Modified) was included in the original request these will be sent with the new request, which indicates that "this is what I have cached". The server will either send back 204 Not modified ("what you have cached is fine"), or a new 200 OK response with the content of the file.

Adding a no-cache directive forces a validation request to occur each time, but since max-age is also specified the browser will still fall back to the cached version if a 204 response is received.

2
  • This got me headed down the right path, thank you. One thing I did notice, is by using the AppendCacheExtension() method, I actually ended up with a comma delimited list being sent over as the Cache-Control header (e.g. Cache-Control: private, no-cache). So, what I ended up doing instead was context.Response.Cache.SetCacheability(HttpCacheability.NoCache); which seems to do exactly what I was looking for.
    – jtresidder
    Oct 19, 2017 at 15:11
  • You actually want private, max-age=1234, no-cache since that will avoid having to redownload ot of the server version hasn't changed. Otherwise Etag/204 won't be used. Oct 19, 2017 at 19:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.