文件下载(触发浏览器默认下载器)

2,070 阅读2分钟

1000981.jpg

使用场景❤️

近期在处理文件上传过程中,产品文档有一个业务需求:在文件资源管理中,对上传成功(已经处理的文件)进行 批量下载

最初想到的是采用 <a></a> 标签的形式进行,通过动态创建标签来触发“a标签” 的 download 属性进行文件的下载。下载单个文件时,还是可以正常下载的;当对选中文件进行批量下载时,就会出现阻塞问题,导致下载失败。

解决方案 🐯

查阅MDN官方文档和一些博客网站,找到了适合当前需求的解决方法:

采用动态创建“iframe”标签的形式,来触发文件下载,并对新创建的“iframe”标签进行动态创建和样式的隐藏;通过隐藏动态创建的标签来减少对当前页面的干扰,相对于“a标签”的形式,“iframe标签”下载文件时不会受到“跨域”的影响。

Suggestion (2).gif

代码实例 🐵

文件下载:
/**
 * @description 下载文件
 * @param {string} fileUrl 文件链接地址
 **/
export const downloadFile = fileUrl => {
	const iframe = document.createElement("iframe");
	// 防止影响页面布局
	iframe.style.display = "none";
	iframe.style.height = 0;
	iframe.src = fileUrl;
	document.body.appendChild(iframe);
	// 加载完成后移除创建的标签
	iframe.onload = function () {
		document.body.removeChild(iframe);
	};
};
获取媒体文件时长
/**
 * @description 获取音/视频时长
 * @param {string/object} file 文件地址/对象
 * @return {number} 媒体文件时长
 **/
export const getMediaDuration = file => {
	return new Promise(resolve => {
		// 是否是文件对象
		let hasFile = file instanceof File;
		let fileUrl = hasFile ? URL.createObjectURL(file) : file;
		// 创建对象
		let audioElement = new Audio(fileUrl);
		// 监听对象
		audioElement.addEventListener("loadedmetadata", () => {
			let time = Math.floor(audioElement.duration) || 0;
			resolve(time);
		});
		// 加载失败
		audioElement.addEventListener("error", () => {
			resolve(0);
		});
	});
};
注:

在处理本地文件上传或者在线文件检测时,需要获取本地上传文件或者在线媒体文件的时长信息,用作观看或学习记录的时间的统计,从而以便于计算和统计当前用户的学习进度。

通过监听动态创建的媒体标签的 “loadedmetadata” 来获取文件的时长。

总结 🧲

好记性不如烂笔头。

记录工作生活中的点滴...