1. a標(biāo)簽
點(diǎn)擊a 標(biāo)簽,可以直接下載其href屬性對(duì)應(yīng)的文件忽你,文件名為download屬性的對(duì)應(yīng)值阶女。
< a href = " /images/logo.png " download = " /images/logo.png " >
可以用js動(dòng)態(tài)生成一個(gè)a標(biāo)簽痘煤,模擬點(diǎn)擊事件進(jìn)行下載
缺點(diǎn):不能獲取成功事件和異常事件
export const useATagDownLoad = (fileName, objectUrl) => {
const el = document.createElement('a');
el.download = fileName;
el.style.display = 'none';
el.href = objectUrl;
document.body.appendChild(el);
el.click();
document.body.removeChild(el);
};
2. form 表單
利用form表單的submit功能,可以實(shí)現(xiàn)文件的下載
效果 :在 當(dāng)前頁面打開一個(gè)下載彈框瓦胎,實(shí)現(xiàn)文件的下載
缺點(diǎn):不能獲取成功事件和異常事件
export const useFormDownload = (url, params) => {
// 導(dǎo)出表格
const form = document.createElement('form');
form.id = 'form';
form.name = 'form';
document.body.appendChild(form);
for (const obj in params) {
if (params.hasOwnProperty(obj)) {
const input = document.createElement('input');
input.type = 'hidden';
input.name = obj;
input.value = params[obj];
form.appendChild(input);
}
}
form.method = 'GET'; // 請(qǐng)求方式
form.action = url;
form.submit();
document.body.removeChild(form);
};
3. window.open( url)
window.open(url)會(huì)打開一個(gè)新的窗口進(jìn)行下載芬萍,下載成功后會(huì)自動(dòng)關(guān)閉新窗口,通過監(jiān)聽新窗口的breforeunload事件搔啊,可以知道下載成功了
缺點(diǎn):不能獲取異常事件
const net = await window.open(url);
net.addEventListener('beforeunload', (e) => {
// 下載成功了
this.appraisalDownLoading = false;
});
4. ajax + window.URL. createObjectURL + a標(biāo)簽
ajax請(qǐng)求拿到文件數(shù)據(jù)后柬祠,利用 window.URL.createObjectURL 創(chuàng)建文件的url,利用a標(biāo)簽下載這個(gè)url.
優(yōu)點(diǎn):可以知道下載成功负芋,可以catch異常
需要注意的是:我們是用http響應(yīng)頭的Content-Disposition:attachment; filename 中的finename
當(dāng)做文件名,后端一般是用utf-8編碼漫蛔,而Http 消息只能是 ASCII 編碼,所以文件名可能會(huì)出現(xiàn)亂碼情況,需要后端返回 urlencode 后的finename
參考博客:https://www.cnblogs.com/saryli/p/5455362.html
import axios from 'axios';
import FileType from 'file-type';
export const downloadFile = (path, params) => {
return axios.get(`${path}`, {
params,
responseType: 'arraybuffer',
});
};
export const downloadToObjectUrl = (() => {
return async (path, params) => {
try {
const res = await downloadFile(path, params);
const { headers } = res;
// 失敗時(shí)返回的json
if (headers && headers['content-type'].includes('json')) {
throw new Error('fail');
}
const buffer = res.data;
const result = await FileType.fromBuffer(buffer);
const blob = new Blob([buffer], {
type: result && result.mime,
});
const objectUrl = window.URL.createObjectURL(blob);
const fileNameMatch = (res.headers['content-disposition'] || '').match(
/filename="(.*)"/
);
return {
fileHash: params.fileHash,
fileName: fileNameMatch ? decodeURIComponent(fileNameMatch[1]) : '', // include suffix
objectUrl,
};
} catch (e) {
throw e;
}
};
})();
export const useFormDownload = (url, params) => {
// 導(dǎo)出表格
const form = document.createElement('form');
form.id = 'form';
form.name = 'form';
document.body.appendChild(form);
for (const obj in params) {
if (params.hasOwnProperty(obj)) {
const input = document.createElement('input');
input.type = 'hidden';
input.name = obj;
input.value = params[obj];
form.appendChild(input);
}
}
form.method = 'GET'; // 請(qǐng)求方式
form.action = url;
form.submit();
document.body.removeChild(form);
};
const { fileName, objectUrl } = await downloadToObjectUrl(url, params);
useATagDownLoad(fileName, objectUrl);