本文未完结,持续更新中......
从指定URL下载网络资源
/**
*
* @param url 欲下载资源的URL
* @param {function} loading_callback - 下载进度回调函数,参数为下载进度百分比(精确到两位小数)
* @param {function} finished_callback - 下载完成回调函数,参数为下载任务ID
* @param {number} id - 下载任务ID
* @returns {Promise<Blob>} - 包含下载内容的 Blob 对象的 Promise
*/
export function downloadWithProgress(url, loading_callback, finished_callback, id) {
return new Promise((resolve, reject) => {
fetch(url).then(response => {
const totalBytes = response.headers.get('Content-Length');
let downloadedBytes = 0;
const reader = response.body.getReader();
const chunks = [];
function read() {
reader.read().then(({ done, value }) => {
if (done) {
const blob = new Blob(chunks);
finished_callback && finished_callback(id);
resolve(blob);
return;
}
chunks.push(value);
downloadedBytes += value.length;
const progress = (downloadedBytes / totalBytes) * 100;
loading_callback && loading_callback(progress.toFixed(2), id);
// console.log(`下载进度:${progress.toFixed(2)}%`);
// 继续读取下一块数据
read();
}).catch(error => {
reject(error);
});
}
read();
}).catch(error => {
reject(error);
});
});
}
- downloadWithProgress 函数接受四个参数:
- url:欲下载资源的 URL。
- loading_callback:下载进度回调函数,参数为下载进度百分比(精确到两位小数)和下载任务的 ID。
- finished_callback:下载完成回调函数,参数为下载任务的 ID。
- id:下载任务的 ID。
- 函数返回一个 Promise,其中包含一个 Blob 对象,表示下载的内容。
- 在函数体内部,通过 fetch 方法发送 HTTP 请求获取资源。
- 通过 response.headers.get('Content-Length') 获取资源的总字节数。
- 创建一个 reader 对象来读取响应体的数据。
- 定义一个 chunks 数组,用于存储每个数据块。
- 定义 downloadedBytes 变量来跟踪已下载的字节数。
- 使用 reader.read() 方法逐块读取数据,并在每次读取完成后执行回调函数。
- 在读取完成后,将所有数据块组合成一个 Blob 对象。
- 调用 finished_callback 回调函数,通知下载任务已完成。
- 最终,通过 resolve(blob) 返回包含下载内容的 Blob 对象。
使用举例:
// ...
let a = a_ref.current;
downloadWithProgress(data.url, showDownloadProgress, finished_callback, 1).then(blob => {
a.href = URL.createObjectURL(blob);
a.download = data.title + '.mp4';
a.click();
});
// ...
Blob URL
可以使用URL.createObjectURL()
同步函数将获得的Blob变量生成一个内存URL(Blob URL,生命周期仅限当前标签页的document)
「createObjectURL
返回一段带hash的url,并且一直存储在内存中,直到document触发了unload
事件(例如:document close)或者执行revokeObjectURL
来释放。」
然后可以将某个a标签的href
属性设置为该URL,之后触发点击该a标签即可完成下载(从内存下载到磁盘)。
另外,回调函数搭配其他组件可以实现监控下载进度,反馈下载情况。
比如:
const showDownloadProgress = (progress, id) => {
notify_loading(<span>正在下载视频: <span style={{ color: 'rgb(96, 165, 250)', width: '66px', display: 'inline-block', textAlign: 'right' }}>{progress}%</span></span>, 'downloading_video' + id);
};
const finished_callback = (id) => {
toast.dismiss('downloading_video' + id);
notify_success('视频下载完毕 !', 'finished_video' + id);
}
这里调用配置好的toast
库的气泡通知组件,可以实时显示远程资源的下载进度以及完成下载的通知。
Web Share API 与 File类
Web Share API用来进行文件分享,打通系统级分享API,目前支持的浏览器较少,仅Mac端Safari和移动端的Safari、Chrome等浏览器支持。且只能通过用户的直接操作唤起,比如click
点击事件。
File类是Blob类的子类,可以通过new File([blob], title)
的形式创建(注意参数是Blob数组)。
let title = `P${item.index + 1} - ${item.title}.mp4`;
let file = new File([blob], title);
if (navigator.canShare && navigator.canShare({ files: [file] })) {
navigator.share({
files: [file],
title: title,
text: title,
}).then(r => notify_success('视频' + (item.index + 1) + '分享成功 !', 'share_video_success' + (item.index + 1)))
.catch(e => {
console.log(e);
notify_error('视频' + (item.index + 1) + '分享失败 !', 'share_video_error' + (item.index + 1));
})
}
Data URL
通过FileReader.readAsDataURL(file)
可以获取一段data:base64
的字符串,FileReader.readAsDataURL()
是异步执行(过一段时间)。
FileReader.readAsDataURL()
返回包含很多字符的base64(URL本身包含了全部数据),会比blob url消耗更多内存,但是在不用的时候会自动从内存中清除(通过垃圾回收机制)。
如果不太在意设备性能问题,并想获取图片的base64,则推荐使用FileReader.readAsDataURL()
。
示例:
<input type="file" id="btn" accept="image/*" value="点击上传" />
<img id="img"/>
btn.addEventListener('change',function(){
let file = this.files[0];
// 进一步防止文件类型错误
if(!/image\/\w+/.test(file.type)){
alert("看清楚,这个需要图片!");
return false;
}
img.src = URL.createObjectURL(file)
})
Blob URL和Data URL的区别
在JavaScript中,Blob URL和Data URL都是用来表示数据的特殊URL格式。
Blob URL是用于表示二进制数据的URL,可以通过URL.createObjectURL()
方法创建。它接受一个Blob对象作为参数,并返回一个用于访问该Blob数据的URL。Blob URL通常用于在浏览器中显示或下载二进制文件,比如图片、音频、视频等。
以下是使用Blob URL的示例代码:
// 创建一个Blob对象
const blob = new Blob([data], { type: 'image/png' });
// 生成Blob URL
const blobURL = URL.createObjectURL(blob);
// 在img元素中显示图片
const img = document.createElement('img');
img.src = blobURL;
document.body.appendChild(img);
// 释放Blob URL
URL.revokeObjectURL(blobURL);
Data URL是一种用于表示数据的URL格式,可以直接包含数据内容,通常以data:
开头。Data URL将数据编码为Base64格式,并包含数据的MIME类型,可以直接在URL中嵌入数据内容。Data URL适用于将小型数据嵌入到网页中,比如小图片或CSS背景图等。
以下是使用Data URL的示例代码:
// 将文本数据转换为Data URL
const data = 'Hello, World!';
const dataURL = `data:text/plain;charset=utf-8,${encodeURIComponent(data)}`;
// 在a标签中添加下载链接
const a = document.createElement('a');
a.href = dataURL;
a.download = 'text.txt';
a.textContent = 'Download';
document.body.appendChild(a);
请注意,Data URL适用于小型数据,对于大型数据(比如大图像或大文件),Data URL可能会导致性能问题和内存消耗过大,因此更适合用于小型数据的嵌入。而对于大型数据的处理,Blob URL通常更合适。
Comments NOTHING