前言:在一個vue項目開發(fā)過程中, 遇到了一個跨域下載文件的功能, 記錄一下踩過的坑。
場景:在開發(fā)過程中, 遇到一個上傳下載的功能, 由于是把文件放到騰訊云上的, 所以當(dāng)下載的時候會出現(xiàn)跨域的問題.
后臺返回數(shù)據(jù)如下:
filename線上文件名 (為了防止重復(fù)發(fā)生文件覆蓋問題, 后臺將上傳的文件重命名)full_url文件的線上鏈接mime文件的 Content-Type 類型original_name文件上傳時的本地命名
采坑過程:
1.由于當(dāng)時未知跨域問題, 直接使用了 超鏈接 下載
<div
class="item"
v-for="(item, ind) in taskDetailData.art_files"
:key="ind"
>
<a :href="item.full_url" :download="original_name">
<div class="item_text">{{ item.original_name }}</div>
<div class="icon_box">
<icon icon="download"></icon>
</div>
</a>
</div>
測試結(jié)果:
可以看到,rar類型,xlsx文件都能下載下來, 可是text類型,filename, 并不是我們想要的original_name所以, 超鏈接下載不是我們想要的
- 使用
axios并且轉(zhuǎn)化為Blob發(fā)送請求進行下載
<div
class="item"
v-for="(item, ind) in taskDetailData.art_files"
:key="ind"
>
<a @click="handleDownload(item.full_url, item.original_name, item.mime)">
<div class="item_text">{{ item.original_name }}</div>
<div class="icon_box">
<icon icon="download"></icon>
</div>
</a>
</div>
import axios from "axios";
methods: {
handleDownload(url, fileName, mime) { // 下載附件
axios.get(url, { responseType: 'blob' })
.then(res => {
let blob = new Blob([res.data], { type: mime })
// 注: mime類型必須整正確, 否則下載的文件會損壞
if (window.navigator && window.navigator.msSaveOrOpenBlob) { // 兼容IE
window.navigator.msSaveOrOpenBlob(blob, element.original_name);
} else {
let downloadElement = document.createElement('a');
downloadElement.href = window.URL.createObjectURL(blob); // 創(chuàng)建一個DOMString
downloadElement.download = fileName;
downloadElement.click();
window.URL.revokeObjectURL(blob); // 釋放 DOMString ,解除內(nèi)存占用
}
})
.catch(error => {
console.error(error)
})
}
}
測試結(jié)果:下載成功, 什么類型都可以下載, 文件名字也是我們想要的.
總結(jié)
由于文件放在騰訊云上, 所以這是跨域下載, 由于安全性的問題, 瀏覽器是不允許跨域下載的, 所以我們需要先把需要下載的文件獲取下來在本地轉(zhuǎn)化為 Blob 二進制流, 再進行下載就沒有了跨域的問題


