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 也可以进行差不多的判断处理,但代码我找不到了,这里就不贴了。