使用a标签下载文件
引言
HTML中 <a>
元素(或称锚元素)可以通过它的 href
属性创建通向其他网页、文件、电子邮件地址、同一页面内的位置或任何其他 URL 的超链接。
<a>
中的内容应该指明链接的目标。如果存在 href
属性,当 <a>
元素聚焦时按下回车键就会激活它。
本文主要讲解如何通过a标签来下载文件。
download属性
浏览器将链接的 URL 视为下载资源。可以使用或不使用 filename
值:
如果没有指定值,浏览器会从多个来源决定文件名和扩展名:
Content-Disposition
HTTP 标头。- URL的最后一段。
- 媒体类型。来自
Content-Type
标头,data:
URL的开头,或blob:
URL 的Blob.type
filename
:决定文件名的值。/
和\
被转化为下划线(_
)。文件系统可能会阻止文件名中其他的字符,因此浏览器会在必要时适当调整文件名。
备注:
download
只在同源 URL
或blob:
、data:
协议起作用。- 浏览器对待下载的方式因浏览器、用户设置和其他因素而异。在下载开始之前,可能会提示用户,或者自动保存文件,或者自动打开。自动打开要么在外部应用程序中,要么在浏览器本身中。
- 如果
Content-Disposition
标头的信息与download
属性不同,产生的行为可能不同:- 如果文件头指定了一个
filename
,它将优先于download
属性中指定的文件名。- 如果标头指定了
inline
的处置方式,Chrome 和 Firefox 会优先考虑该属性并将其视为下载资源。旧的 Firefox 浏览器(版本 82 之前)优先考虑该标头,并将内联显示内容。
下载方式
1. 直接使用a标签的href属性指定文件的URL
可以在a标签中使用href属性指定文件的URL,点击链接时会直接下载文件。
<a href="file_url">Download</a>
优点:简单易用,只需在a标签中指定文件的URL即可。
缺点:无法控制下载文件的名称和保存位置。
2. 使用download属性指定下载文件的名称
可以在a标签中使用download属性指定下载文件的名称,点击链接时会将文件以该名称保存到本地。
<a href="file_url" download="file_name">Download</a>
优点:可以控制下载文件的名称。
缺点:无法控制下载文件的保存位置。
3. 将文件数据转为Blob进行下载
当需要将文件数据转为Blob或Base64进行下载时,可以使用以下方法:
1. 将文件数据转为Blob进行下载
function downloadFile(data, filename, type) {
const blob = new Blob([data], { type: type });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
function fileToBlob(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => {
resolve(new Blob([reader.result], { type: file.type }));
};
reader.onerror = reject;
reader.readAsArrayBuffer(file);
});
}
// 使用示例
const fileData = ...; // 文件数据
const fileName = 'example.txt';
const fileType = 'text/plain';
fileToBlob(fileData).then(blob => {
downloadFile(blob, fileName, fileType);
});
首先,我们定义了一个名为downloadFile
的函数,它接受三个参数:文件数据(data),文件名(filename)和文件类型(type)。 在函数内部,我们使用Blob
构造函数将文件数据和类型传递给它,从而创建一个Blob对象。然后,我们使用URL.createObjectURL()
方法创建一个URL,该URL指向Blob对象。 接下来,我们创建一个<a>
元素,并设置其href属性为之前创建的URL,并将下载属性设置为指定的文件名。然后将该元素添加到文档的body中。 最后,我们模拟用户点击该链接进行下载,并在完成后清理相关资源。
在使用时,我们首先调用fileToBlob
函数将文件数据转换为Blob对象。该函数返回一个Promise对象,在Promise的resolve回调中返回了转换后的Blob对象。 然后,在Promise的回调中调用了downloadFile
函数来进行下载。
2. 将文件数据转为Base64进行下载
function downloadBase64File(base64Data, filename, type) {
const byteCharacters = atob(base64Data);
const byteArrays = [];
for (let i = 0; i < byteCharacters.length; i++) {
byteArrays.push(byteCharacters.charCodeAt(i));
}
const blob = new Blob([new Uint8Array(byteArrays)], { type: type });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => {
resolve(reader.result.split(',')[1]);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
// 使用示例
const fileData = ...; // 文件数据
const fileName = 'example.txt';
const fileType = 'text/plain';
fileToBase64(fileData).then(base64Data => {
downloadBase64File(base64Data, fileName, fileType);
});
首先,我们定义了一个名为downloadBase64File
的函数,它接受三个参数:Base64字符串(base64Data),文件名(filename)和文件类型(type)。 在函数内部,我们首先将Base64字符串解码为字节数组,并将其存储在byteArrays
数组中。然后,我们使用这些字节数组创建一个Blob对象,并使用URL.createObjectURL()
方法创建一个URL。 接下来,我们创建一个<a>
元素,并设置其href属性为之前创建的URL,并将下载属性设置为指定的文件名。然后将该元素添加到文档的body中。 最后,我们模拟用户点击该链接进行下载,并在完成后清理相关资源。
在使用时,我们首先调用fileToBase64
函数将文件数据转换为Base64字符串。该函数返回一个Promise对象,在Promise的resolve回调中返回了转换后的Base64字符串。 然后,在Promise的回调中调用了downloadBase64File
函数来进行下载。
总结
您可以根据需要选择将文件数据转为Blob或Base64进行下载。如果您已经有文件数据,可以使用fileToBlob
函数将其转为Blob对象并进行下载。如果您希望将文件数据转为Base64进行下载,可以使用fileToBase64
函数将其转为Base64字符串,并使用downloadBase64File
函数进行下载。
来源:juejin.cn/post/7291200719683502120