如何使 pdf 文件在浏览器里面直接下载而不是打开?

936 阅读2分钟

做项目的时候遇到一个情况:当我需要直接下载服务端pdf文件的时候,发现直接打开了pdf文件,而不是直接下载,查阅资料后发现,pdf,视频等文件浏览器是可以直接预览的,所以当在浏览器拿取服务端的文件地址时会触发自动预览功能,那么如何使 pdf 文件在浏览器里面直接下载而不是打开?以下提供几种思路

1.前端自己处理:
/**
 * @deprecated 处理 pdf url,使其不在浏览器直接打开
 * @param {string} url
 * @param {string} name
 */
export const downloadFile = (url: string, name: string) => {
  //url是pdf链接
  axios
    .get(url, {
      responseType: "arraybuffer"
    })
    .then((res: any) => {
      const fileName = name
      download(res, fileName)
    })
}

export const download = (res: any, filename: any) => {
  // 创建blob对象,解析流数据
  const blob = new Blob([res.data])
  const a = document.createElement("a")
  // 兼容webkix浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
  const URL = window.URL || window.webkitURL
  // 根据解析后的blob对象创建URL 对象
  const herf = URL.createObjectURL(blob)
  // 下载链接
  a.href = herf
  // 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'
  a.download = filename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  // 在内存中移除URL 对象
  window.URL.revokeObjectURL(herf)
}

手写两个方法,然后让浏览器创建blob对象,这种方式不太推荐,因为在点击下载的过程,浏览器会先去生成blob,当文件很大或者网速不好的情况下,这显然是一个耗时操作,且用户体验非常不好。

2.Nginx处理
location ^~ /source
        {
          add_header Content-Disposition attachment;
          #允许跨域请求的域,*代表所有
          add_header 'Access-Control-Allow-Origin' *;
          #允许请求的方法,比如 GET/POST/PUT/DELETE
          add_header 'Access-Control-Allow-Methods' 'GET';
          #允许请求的header
          add_header 'Access-Control-Allow-Headers' *;
          
          alias  /www/source/;
          
        }

比如我的服务端文件地址是通过source代理,可以通过配置 add_header Content-Disposition attachment;告诉浏览器这是可以附加下载

Content-Disposition属性有两种类型:inline 和 attachment inline :将文件内容直接显示在页面 attachment:弹出对话框让用户下载:disposition-type是以什么方式下载,如attachment为以附件方式下载

或者

location ^~ /source
        {
           types {
           application/octet-stream pdf;
          }
         default_type application/octet-stream;
          #允许跨域请求的域,*代表所有
          add_header 'Access-Control-Allow-Origin' *;
          #允许请求的方法,比如 GET/POST/PUT/DELETE
          add_header 'Access-Control-Allow-Methods' 'GET';
          #允许请求的header
          add_header 'Access-Control-Allow-Headers' *;
          
          alias  /www/source/;
          
        }

配置 types { application/octet-stream pdf; } default_type application/octet-stream; 告诉浏览器通过字节流的形式强行更改type