注册
web

使用a标签下载文件

引言


HTML中  <a>  元素(或称元素)可以通过它的 href 属性创建通向其他网页、文件、电子邮件地址、同一页面内的位置或任何其他 URL 的超链接。


<a> 中的内容应该指明链接的目标。如果存在 href 属性,当 <a> 元素聚焦时按下回车键就会激活它。


本文主要讲解如何通过a标签来下载文件。


download属性


浏览器将链接的 URL 视为下载资源。可以使用或不使用 filename 值:




  • 如果没有指定值,浏览器会从多个来源决定文件名和扩展名:



    • Content-DispositionHTTP 标头。
    • 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

0 个评论

要回复文章请先登录注册