如何使 pdf 文件在瀏覽器裡面直接下載而不是打開
- 2020 年 8 月 10 日
- 筆記
- javascript, 前端學習
前言
在做需求過程中我們大概率會遇到在瀏覽器中下載文件的需求,如果僅僅是這個要求的話很簡單,有如下兩種解決方式。
第一種是通過 window 對象的 open 方法進行操作,將文件 url 直接在瀏覽器中打開即可下載。
window.open('url')
第二種是通過 a 標籤,設置 href 為 url 值,點擊 a 標籤即可完成下載。
<a href='url' download='文件名'></a>
但是上面兩種文件下載方式都會存在一個問題,就是 pdf 文件會直接在瀏覽器中打開而不是直接下載,效果如下:
解決方案
這種需求的解決方式就是將PDF文件的 MIME type 改為 application/octet-stream
並加入 Content-Disposition:attachment
header,原本的 pdf 文件 MIME type 為 application/pdf
,瀏覽器識別到這個 type 之後會自動在瀏覽器打開,所以說我們在這裡修改 type 即可。
修改的方法有兩種,一種是在後端進行修改,上傳文件或者返迴文件的時候進行操作,但是絕大多數情況下文件都是存儲到 cdn 伺服器中的,後端也不方便對其進行操作,這個時候就需要前端來修改了。
處理程式碼如下:
/**
* @deprecated 下載文件
* @param {string} url
* @param {string} filename
*/
handleFileDownload = (url, filename) => {
// 創建 a 標籤
let a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
}
/**
* @deprecated 處理 pdf url,使其不在瀏覽器打開
* @param {string} url
*/
handlePdfLink = (url, filename) => {
fetch(url, {
method: 'get',
responseType: 'arraybuffer',
})
.then(function (res) {
if (res.status !== 200) {
return res.json()
}
return res.arrayBuffer()
})
.then((blobRes) => {
// 生成 Blob 對象,設置 type 等資訊
const e = new Blob([blobRes], {
type: 'application/octet-stream',
'Content-Disposition':'attachment'
})
// 將 Blob 對象轉為 url
const link = window.URL.createObjectURL(e)
handleFileDownload(link, filename)
}).catch(err => {
console.error(err)
})
}
這樣修改修改程式碼的話就可以實現在瀏覽器中下載。效果如下