react实现文件下载
使用 fetch 或 axios 下载文件
通过 fetch 或 axios 请求文件数据,将响应转换为 Blob 对象,并创建下载链接。以下是一个示例代码:
const downloadFile = async (url, filename) => {
try {
const response = await fetch(url);
const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error('Error downloading file:', error);
}
};
使用 a 标签直接下载
对于不需要鉴权的文件,可以直接通过 a 标签的 download 属性实现下载:
const downloadFile = (url, filename) => {
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
处理后端返回的文件流
如果后端返回文件流(如 PDF、Excel 等),可以通过设置响应类型为 blob 并处理:
const downloadFile = async (url, filename) => {
try {
const response = await axios.get(url, { responseType: 'blob' });
const blob = new Blob([response.data]);
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error('Error downloading file:', error);
}
};
处理大文件分片下载
对于大文件,可以分片下载并合并:
const downloadLargeFile = async (url, filename) => {
try {
const response = await fetch(url);
const reader = response.body.getReader();
const chunks = [];
let receivedLength = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
receivedLength += value.length;
}
const blob = new Blob(chunks);
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error('Error downloading large file:', error);
}
};
添加下载进度提示
通过监听 axios 或 fetch 的进度事件,显示下载进度:
const downloadFileWithProgress = (url, filename) => {
axios({
url,
method: 'GET',
responseType: 'blob',
onDownloadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`Download progress: ${percentCompleted}%`);
},
}).then((response) => {
const blob = new Blob([response.data]);
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
});
};
注意事项
- 跨域问题:确保后端配置了 CORS 允许前端访问文件。
- 文件名:后端可以通过响应头
Content-Disposition指定文件名,前端可以从响应头中解析。 - 错误处理:捕获并处理网络请求或文件操作中的错误。







