Eric Niquette

Introduction

In some situations, it may be preferable to force the download of PDF documents so that they can be saved locally rather than rely on the browser's built-in reader. This is particularly common when dealing with forms where the capture of partial data and caching come into play.

Triggering the download of documents can be done in a few different ways, but I'll mainly be touching on the HTML download attribute and the server's response headers.

Download attribute

In HTML, you can ask the browser to download a link's destination content using the download attribute in an anchor element.

<a href="files/download.pdf" download>Download my PDF document</a>

It should be noted that the attribute will typically take precedence over server configurations.

Server response and headers

If the HTML attribute doesn't work or if you need to apply a change globally, the server's headers can be modified to respond to a PDF request as a generic data stream and as an attachment.

The Windows web.config and Apache .htaccess configuration files contain instructions, rules, and other variables that apply to the server. The files are typically found in the root home folder and propagate down, applying to every folder and subfolder. Configuration files can also be added to specific folders if they should only affect particular files.

Care should be taken whenever you modify configuration files. I can only strongly recommend that you perform a backup before making any changes.

MIME types are used to tell the browser how it should identify and interpret a file. The default value of application/pdf is stripped and re-defined as a generic data stream of no particular format.

Response headers tell the browser what to do with a document; either attempt to display in inline or download it as an attachment. In this case, it is forced as an attachment.

.htaccess

<FilesMatch "\.(pdf)$">
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</FilesMatch>

web.config

<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Set Content Type and Disposition for PDF">
          <match url=".*\.pdf$" />
          <action type="Rewrite" url="{R:0}" />
          <serverVariables>
            <set name="RESPONSE_CONTENT_TYPE" value="application/octet-stream" />
            <set name="RESPONSE_CONTENT_DISPOSITION" value="attachment" />
          </serverVariables>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Note that this requires the server to be configured to allow variables. If it's not, you can add the following to allow variables to RESPONSE_CONTENT_TYPE and RESPONSE_CONTENT_DISPOSITION. You'll need your website's IIS name, which can be found in the management console.

<location path="IIS website name">
  <system.webServer>
    <rewrite>
      <allowedServerVariables>
        <add name="RESPONSE_CONTENT_TYPE" />
        <add name="RESPONSE_CONTENT_DISPOSITION" />
      </allowedServerVariables>
    </rewrite>
  </system.webServer>
</location>