在前端開發中,實現文件下載是常見的需求。根據不同的場景,我們可以選擇不同的方法來實現文件流的下載。本文介紹三種常用的文件下載方式:
- 使用
axios
發送 JSON 請求下載文件流 - 使用
axios
發送FormData
請求下載文件流 - 使用原生
form
表單提交下載文件流
一、使用 Axios 下載文件流(JSON 格式參數)
? 適用場景:
適用于需要通過 POST 請求發送 JSON 數據給后端以獲取文件流的情況。
?? 注意事項:
- 設置
responseType: 'blob'
。 - 使用
Blob
對象處理響應數據。 - 動態獲取文件名需依賴
Content-Disposition
頭部字段,部分瀏覽器可能不支持,需服務器配置允許跨域訪問該頭部。
🧩 示例代碼:
axios({url: 'https://localhost/download/test',method: 'post',data: {headers: ["姓名", "年齡", "城市"],data: [{"姓名": "張三","年齡": 25,"城市": "北京"}],fileName: "99"},responseType: 'blob',withCredentials: true
}).then(response => {// 獲取文件名let filename = '默認文件.xlsx';const disposition = response.headers['content-disposition'];if (disposition && disposition.indexOf('filename=') !== -1) {filename = disposition.split('filename=')[1].replace(/"/g, '');try {filename = decodeURIComponent(filename);} catch (e) {filename = unescape(filename);}}// 創建 Blob 并觸發下載const blob = new Blob([response.data], { type: response.headers['content-type'] });const url = window.URL.createObjectURL(blob);const link = document.createElement('a');link.href = url;link.download = filename;document.body.appendChild(link);link.click();window.URL.revokeObjectURL(url);document.body.removeChild(link);
});
二、使用 Axios 下載文件流(FormData 格式參數)
? 適用場景:
適用于需要傳遞鍵值對形式的數據(如上傳文件)或模擬表單提交的場景。
?? 注意事項:
- 設置請求頭為
'application/x-www-form-urlencoded'
。 - 使用
FormData
構造請求體。 - 同樣需要處理動態文件名。
🧩 示例代碼:
const formData = new FormData();
formData.append("key", "value");axios({url: 'http://localhost/api/download',method: 'post',data: formData,headers: {'Content-Type': 'application/x-www-form-urlencoded'},responseType: 'blob',withCredentials: true
}).then(response => {const disposition = response.headers['content-disposition'];let filename = '默認文件.xlsx';if (disposition && disposition.includes('filename=')) {filename = disposition.split('filename=')[1].replace(/"/g, '');try {filename = decodeURIComponent(filename);} catch (e) {filename = unescape(filename);}}const blob = new Blob([response.data], { type: response.headers['content-type'] });const url = window.URL.createObjectURL(blob);const link = document.createElement('a');link.href = url;link.download = filename;document.body.appendChild(link);link.click();window.URL.revokeObjectURL(url);document.body.removeChild(link);
});
三、使用原生 Form 表單提交下載文件流
? 適用場景:
適用于不需要 JavaScript 控制、直接通過表單提交參數并由后端返回文件流的場景。
?? 注意事項:
- 需要手動創建隱藏的
<form>
元素。 - 不適合處理 Blob 文件流(無法控制下載行為)。
- 不支持異步操作,頁面會跳轉。
🧩 示例代碼:
const paraData = { id: 1212, name: '測試名' };
const formActionUrl = gateUrl + '/api/dictData/downloadDictDataList';const form = document.createElement('form');
form.style.display = 'none';
form.action = formActionUrl;
form.method = 'post';
form.enctype = 'application/x-www-form-urlencoded'; // 可選document.body.appendChild(form);for (let key in paraData) {if (paraData.hasOwnProperty(key)) {const input = document.createElement('input');input.type = 'hidden';input.name = key;input.value = paraData[key];form.appendChild(input);}
}form.submit(); // 提交表單
form.remove(); // 移除表單
? 總結對比
方法 | 是否支持 JSON | 是否支持文件下載 | 是否支持動態文件名 | 是否異步 | 是否推薦 |
---|---|---|---|---|---|
Axios + JSON | ? | ? | ?(依賴響應頭) | ? | ? 推薦 |
Axios + FormData | ?(自動轉換) | ? | ? | ? | ? 推薦 |
原生 Form | ? | ? | ? | ? | ?? 視情況 |
🔁 補充建議
- 封裝統一下載工具函數:將通用邏輯提取成工具函數,提高復用性。
- 兼容中文文件名:建議后端統一使用 UTF-8 編碼文件名,避免前端解析困難。
- 錯誤處理增強:添加
.catch()
捕獲異常并提示用戶。 - 取消請求機制:對于大文件或長時間請求,可考慮加入取消功能(如
CancelToken
或AbortController
)。