最近有个需求,后端把pdf文件直接传给后端,前端不用下载然后做网页端预览。
pdf预览的话如果知道文件的绝对路径,可以就用一个<a>
标签,href属性设为此路径,(<embed>/<iframe>/<object>等标签在有文件路径的情况下都可以直接浏览器预览)
点击即可浏览器预览。但是问题是,这个获取pdf文件的接口需要做token校验,而且也不是直接返回一个文件路径给到前端,返回的是二进制数据,需要前端自己处理。
后端返回内容如下:
直接搜"二进制pdf文件在线预览"会查到很多相关的资料,看了下用的最多的那种方法:用法如下:
axios({
url: '/wx/informationentry/download',
methods: 'get',
baseURL: BASE_URL,
headers: {
Accept: 'application/pdf',
token: getToken(),
responseType: 'blob'
},
params: {
id: row.id
}
}).then((res) => {
console.log('文件下载成功:', res)
const blob = new Blob([res.data], {
type: 'application/pdf;charset=utf-8'
})
// 生成一个本地预览的url
const url = window.URL.createObjectURL(blob)
// 创建一个a标签,设置它的href/target属性,并自动点击
const a = document.createElement('a')
a.href = url
a.target = '_blank'
a.click()
})
不知道是什么原因,这种方法,可以实现预览,但是预览的都是空白内容,搜了下发现,有的说是axios发送的请求的问题,所以这里改成了原始的XMLHttpRequest
方法发送请求。最终我成功实现预览的代码如下:
downloadFileR(row, fileType) {
const xhr = new XMLHttpRequest()
const url = fileType
? `${BASE_URL}/wx/informationentry/download?id=${row.id}&fileType=1`
: `${BASE_URL}/wx/informationentry/download?id=${row.id}`
xhr.open('get', url, true)
xhr.responseType = 'blob' // 这个设置必须要
xhr.setRequestHeader('token', getToken())
xhr.onload = function () {
// 生成url
const binaryData = []
binaryData.push(this.response)
const blob = new Blob(binaryData, {
type: 'application/pdf;charset=utf-8'
})
const url = window.URL.createObjectURL(blob)
// const url = window.URL.createObjectURL(this.response) // 直接这样使用url也可以
const a = document.createElement('a')
a.target = '_blank'
a.href = url
a.click()
}
xhr.send()
}
注意:
-
发送请求时
xhr.responseType = 'blob'
这个设置预览时也是空白的。 -
生成url部分,可以用红框中的代码,也可以直接用绿框中注释掉的代码不用红框的代码。我这里是两种方法在chrome浏览器上都生效的