Table of Contents
对于一个给定链接的文件,如果浏览器可以解析,则会直接预览,否则会触发下载。但实际开发中有可能需要不按照浏览器默认行为处理。比如 pdf,可能需要浏览器直接下载。接下来就以 pdf 为例,记录一下浏览器预览和下载的方法。
预览pdf
对于可以直接访问的链接,a 标签打开就行。
<a><a href="./1182.pdf">download pdf</a>
或者也可以通过请求拿到数据后再触发 a 标签打开。
const btn = document.querySelector('#btn')
btn.addEventListener('click', () => {
fetch('./1182.pdf.bak')
.then(res => {
res.blob()
.then(res => {
const blob = new Blob([res], {type: "application/pdf"})
url = URL.createObjectURL(blob)
window.open(url)
URL.revokeObjectURL(url)
})
})
})
因为是通过请求获取的,所以需要鉴权的话也可以方便地把这些信息加上。
此外,还可以通过 iframe、embed、object 等标签以及 pdfjs 这个包进行预览。
下载 pdf
为了让浏览器不默认打开,可以直接在 a 标签上添加 download 属性。
<a href="./1182.pdf" download>download pdf</a>
download 可以赋值为文件名。我这里就不写了。
同样的,需要鉴权的也可以通过请求拿到数据后创建 a 标签下载。
const btn = document.querySelector('#btn')
btn.addEventListener('click', () => {
fetch('./1182.pdf')
.then(res => {
res.blob()
.then(res => {
const url = window.URL.createObjectURL(new Blob([res]))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', 'test')
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
URL.revokeObjectURL(url)
})
})
})
返回数据类型判断
以上预览和下载 pdf 都是在明确知道链接会返回 pdf 的情况。如果链接/接口在没有 pdf 的情况下返回 json 数据就不好用上面的方法了。这时需要通过请求获取并且对返回值类型进行判断。比如下面 axios 拦截器的处理。
service.interceptors.response.use(
response => {
console.log('request response: ', response)
const res = response.data
// 非 json 格式的数据,直接返回。比如 pdf 之类的
if (response?.headers?.['content-type'] !== 'application/json') {
return res
}
const { error, errno } = res
// 以下各种 errno 的判断省略
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
fetch 也可以进行差不多的判断处理,但代码我找不到了,这里就不贴了。