做项目的时候遇到一个情况:当我需要直接下载服务端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