文件下載:文件下載通常有幾種方法
1.通過url下載
2.location.href
3.form提交直接下載
4.HTML5 a.download結合blob對象進行下載
第一種方式:
第一種方法是前後端的接口只給了一個API請求:
前端第一個實現是使用a標籤,
第二種方式:
這個方法是直接把 DataURLs 或者 BlogURLs 傳到瀏覽器地址中觸發下載。有兩種方式:
window.location.href = urls; // 本窗口打開下載
window.open(urls, '_blank'); // 新開窗口下載
// window.location.href = url+ m.sendcode+"?ids="+ idss+"&type="+type;
此請求有個文件稍大就下載不下來了
第三種:
標籤的download是HTML5標準新增的屬性,作用是指示瀏覽器下載URL而不是導航到URL,因此將提示用戶將其保存爲本地文件。
這種是定義的接口不是下載文件的路徑,而是通過API可以獲得文件的內容,由前端把內容寫入到文件中,這種方法是通過獲取文件信息,在網頁上利用click事件,創建一個文件,然後將文件信息寫入到文件中,然後保存
this.content = content
this.filename = filename
const blob = new Blob([this.content])
if (window.navigator.msSaveOrOpenBlob) {
// 兼容IE10
navigator.msSaveBlob(blob, this.filename)
} else {
// chrome/firefox
let link= document.createElement('a')
link.download = this.filename
link.href = URL.createObjectURL(blob)
link.click()
URL.revokeObjectURL(link.href)
}
第四種form表單
不需要我們處理返回二進制流直接下載,非常方便
form的action設置爲接口地址,method設置爲post,Post到後臺的數據設置爲input的屬性 name = key,value = value的形式,如果有多個key、value的值要傳遞,那麼就設置多個input來分別儲存單個的key、value;
如果請求的接口可以不需要參數,那麼input還是必須要一個,如果不要得話 會引起接口報錯
原理:form的action相當於一個瀏覽器本頁籤/頁面的一個請求,不會被後臺,前臺的路由攔截。所以能夠提交成功。
注意點:如果設置method爲get,在action中的uri添加了參數的話,想用這個參數替代input的key、value形式來提交到後臺,這參數是沒有效果的,後臺拿不到這些參數,真正的參數還是以input的name、value的形式儲存,在submit方法執行後傳遞到後臺。
這樣我們就是實現了文件下載,但是表單提交的數據一般是簡單的鍵值對,如果傳參比較複雜可以考慮將表單序列化提交。
因爲項目是基於vue的,而且提交的請求參數涉及很多參數,比較複雜,所以採用了方法三來實現
功能:點擊導出按鈕,提交請求,下載zip壓縮包文件;
第一步:跟後端交付的接口的response header設置了
response.setContentType("application/octet-stream");// 指明response的返回對象是文件流
response.setHeader("Content-Disposition", "attachment; filename="+type+"_"+code+".zip");
response.setCharacterEncoding("UTF-8");
以及返回了文件流。
第二步:修改axios請求的responseType爲blob,以post請求爲例:
複製代碼
axios({
method: 'post',
url: url,
data: {
參數1: '值',
參數2: '值',
},
responseType: 'blob'
}).then(response => {
this.download(response)
}).catch((error) => {
})
第三步:請求成功,拿到response後,調用download函數(創建a標籤,設置download屬性,插入到文檔中並click)
methods: {
// 下載文件
download (data) {
if (!data) {
return
}
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', 'excel.xlsx')
document.body.appendChild(link)
link.click()
}
}
以下是整個請求的全部代碼
m.loading = true;
m.$axios.post(url,
{
searchkey: m.search,
countycode: m.lpsword,
clasid:m.ltype,
usource:m.lpsource,
type:type
},
{
responseType: 'blob',
}).then(function(response){
let data = response.data;
let headers = response.headers;
if (!data) {
return
}
let url = window.URL.createObjectURL(new Blob([data], {
type: headers['content-type']
}));
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
const fileName = headers['content-disposition'];
let title = fileName.includes('filename=') ? fileName.split('=')[1] :'下載的表單文件';
link.setAttribute('download', title);
document.body.appendChild(link)
link.click()
m.loading = false;
m.$Message.success('數據導出成功');
}, function (error) {
m.$Message.error('數據導出錯誤');
m.loading = false;
})
注意我們發送請求的時候一定要寫上responseType,{responseType: 'blob'} 否則下載下來的文件打不開!!!