一、问题
用户要求pdf文件浏览器直接下载,虽然浏览器直接打开预览时会有下载功能,但是用户就是这么奇葩(狗头保命)。
一开始想到直接拿到pdf的url地址然后使用window.location.href打开即可解决,但是这个还是会在浏览器打开预览(草率了)。
最后百度查到使用如下js代码实现;
function dowanloadpdf(pdfurl) {
axios({
method: 'get',
url: pdfurl,
responseType: 'blob',
}).then(function (response) {
const link = document.createElement('a')
let blob = new Blob([response.data], {type: response.data.type})
let url = URL.createObjectURL(blob)
link.href = url
link.download = '下载文件.pdf'
link.click()
})
}
这个方式如果pdf是本地或同源的话是没问题的,但是正式环境由于pdf地址和网站地址不一致,就产生了跨域问题。
二 解决
瞬间心塞。又是一通百度,网上各种说加什么请求头的,但是均未解决,此时想到曾经一个功能也有同样问题,是通过后台流处理进行解决。那么剩下的就简单了。
链接如下:
pdf.js+turn.js实现Web翻页阅读pdf文件(工作记录)_叩叮ING的博客-优快云博客
以上链接里有后台流处理方法。
拿到流以后,通过js控制a标签进行文件下载,完整js代码
function convertPdf(){
var array ="";
$.ajax({
type:"POST",
async:false, // false是不采用异步的方式
data:{"pdf_url":pdfurl},
mimeType:'text/pdf;charset=x-user-defined',
url:"${rootpath}/special/convertPdf2.jspx",
success:function (data,textStatus, jqXHR) {
//data返回的文件流
var rawLength = data.length;
array = new Uint8Array(new ArrayBuffer(rawLength));
for(var i = 0;i<rawLength;i++){
array[i] = data.charCodeAt(i)&0xff; //转二进制流
}
const link = document.createElement('a')
let blob = new Blob([array], {type:'application/pdf'})
let url = URL.createObjectURL(blob)
link.href = url
link.download = '下载文件.pdf'
link.click()
},
});
}
问题解决,潇洒转身。
三 补充
如果要支持ie和谷歌两个内核的话,用如下方法
//选择浏览器
function downFile(blob, fileName) {//blob就是一中返回的文件,fileName是下载文件名
if (window.navigator.msSaveOrOpenBlob) {//msSaveOrOpenBlob方法返回bool值
navigator.msSaveBlob(blob, fileName);//本地保存
} else {
var link = document.createElement('a');//a标签下载
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
window.URL.revokeObjectURL(link.href);
}
}
参考链接: