18

Currently, when a user clicks on a PDF link on my site (served from the Media Library), the browser will download the PDF file. I'd like to change the behavior from downloading to opening in browser (I am aware that users can change their browser settings to force the behavior they want; I want to change the default behavior).

I know that I need to change the Content-Disposition response header to have inline; instead of attachment;. I could write a pipeline processor to change the Content-Disposition header, but I was hoping Sitecore had a setting for this specific behavior.

My site is currently on Sitecore 8.2 rev 161221.

1
  • I'm trying to reach a similar result to yours, but I'm currently unable to show the PDF link, I'm using Sitecore 9 and SXA 1.7, so i'm using rendering variants to show the pdf fields, but since the field type for the file is "File", it doesn't show anything on the page.. any advice on how to show that? Commented Jun 27, 2018 at 12:35

3 Answers 3

25

The <mediaLibrary><mediaTypes> section of Sitecore.config (or web.config in older versions of Sitecore) contains a <mediatype> element for each file type. Within each mediatype element is a <forceDownload> element. The Content-Disposition header will be set according to the value of the forceDownload setting; attachment; for true, inline; for false.

By default, forceDownload is set to true for PDFs. Changing this value to false will instruct browsers to view the file instead of download.

6
  • 2
    If you do this and it's still not working, make sure the line <mediaType extensions="pdf"><mimeType>application/pdf</mimeType></mediaType> exists, and is not commented out in your app_config/Mimetypes.config Commented Jun 8, 2017 at 16:19
  • Any way to do this on a per file basis? Commented Nov 30, 2017 at 21:20
  • @ZacharyDow: I've not tried this, but you could probably use a custom pipeline to change the response headers before the media item response is sent.
    – Ed Schwehm
    Commented Nov 30, 2017 at 23:56
  • @ZacharyDow please read my answer where I provided a simple solution to do this on a per file basis Commented Oct 3, 2018 at 7:06
  • 1
    It works with Sitecore 9.0.1 - Update 2 too. Thanks!
    – Dash
    Commented Dec 20, 2019 at 3:29
5

You can also easily extend Sitecore to set Content-Disposition per file. To do this, add a new field on File template, located here /sitecore/templates/System/Media/Versioned/File. The best way is to create a new template and make File template to inherit from it.

The new field can be a checkbox named: Set Content Disposition Inline.

Then you have to create your own MediaRequestHandler and set it in Web.config. You can do that with transform file like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <system.webServer>
    <handlers>
      <add verb="*" path="sitecore_media.ashx" type="YourNamespace.MediaRequestHandler, AssemblyName" name="Sitecore.MediaRequestHandler" xdt:Transform="SetAttributes(type)" xdt:Locator="Match(name)" />
    </handlers>
  </system.webServer>
</configuration>

The last piece of course is MediaRequestHandler. You have to create a new class and inherit from existing one. This is how your class can looks like:

public class MediaRequestHandler : Sitecore.Resources.Media.MediaRequestHandler
{
    protected override bool DoProcessRequest(HttpContext context, MediaRequest request, Sitecore.Resources.Media.Media media)
    {
        if (base.DoProcessRequest(context, request, media))
        {
            if (context.Response.StatusCode != 304)
            {
                if (media.MediaData.MediaItem.InnerItem[setContentDispositionFieldId] == "1")
                {
                    var extension = media.Extension;
                    if (extension.Length > 0 && extension[0] != '.')
                    {
                        extension = "." + extension;
                    }

                    var fileName = media.MediaData.MediaItem.Name + extension;

                    context.Response.Headers["Content-Disposition"] = $"inline; filename=\"{fileName}\"";
                }
            }

            return true;
        }

        return false;
    }
}
2
  • 1
    Don't do this! base.DoProcessRequest sends the request so you can't modify the request headers after calling base.DoProcessRequest. If you have a decompiler you can see what I am referring to. Commented Apr 26, 2019 at 21:07
  • Can we handle pdf added in RTE to open in new tab, instead of explicitly mentioning it. Commented Nov 27 at 11:07
1

For Sitecore 9.x and above, follow the below steps to achieve this:

  • Open the App_Config/Sitecore.config and go to <mediaLibrary> section. Change the Force Download for <mediaType name="PDF file" extensions="pdf"> to false. By default, it is true.
<mediaType name="PDF file" extensions="pdf">
        <mimeType>application/pdf</mimeType>
        <forceDownload>false</forceDownload>
        <sharedTemplate>system/media/unversioned/pdf</sharedTemplate>
        <versionedTemplate>system/media/versioned/pdf</versionedTemplate>
      </mediaType>

I'd recommend creating a patch to make this change,

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <!-- Force download of PDF files -->
    <mediaLibrary>
      <mediaTypes>
        <mediaType name="PDF file" extensions="pdf">
          <forceDownload>false</forceDownload>
        </mediaType>
      </mediaTypes>
    </mediaLibrary>
  </sitecore>
</configuration>
  • Open the App_Config/MimeTypes.config and uncomment the below line.
<mediaType extensions="pdf"><mimeType>application/pdf</mimeType></mediaType>

Your Answer

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

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