如何使 pdf 檔案在瀏覽器裡面直接下載而不是開啟
阿新 • • 發佈:2020-08-10
## 前言
在做需求過程中我們大概率會遇到在瀏覽器中下載檔案的需求,如果僅僅是這個要求的話很簡單,有如下兩種解決方式。
第一種是通過 window 物件的 open 方法進行操作,將檔案 url 直接在瀏覽器中開啟即可下載。
```javascript
window.open('url')
```
第二種是通過 a 標籤,設定 href 為 url 值,點選 a 標籤即可完成下載。
```html
```
但是上面兩種檔案下載方式都會存在一個問題,就是 pdf 檔案會直接在瀏覽器中開啟而不是直接下載,效果如下:
![](https://img2020.cnblogs.com/blog/1372160/202008/1372160-20200810202606448-2059431701.gif)
## 解決方案
這種需求的解決方式就是將PDF檔案的 MIME type 改為 `application/octet-stream` 並加入 `Content-Disposition:attachment` header,原本的 pdf 檔案 MIME type 為 `application/pdf`,瀏覽器識別到這個 type 之後會自動在瀏覽器開啟,所以說我們在這裡修改 type 即可。
修改的方法有兩種,一種是在後端進行修改,上傳檔案或者返回檔案的時候進行操作,但是絕大多數情況下檔案都是儲存到 cdn 伺服器中的,後端也不方便對其進行操作,這個時候就需要前端來修改了。
處理程式碼如下:
```javascript
/**
* @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)
})
}
```
這樣修改修改程式碼的話就可以實現在瀏覽器中下載。效果如下
![](https://img2020.cnblogs.com/blog/1372160/202008/1372160-20200810202616508-1381270628.gif)