最近用 Electron 做了个壁纸程序,需要断点续下载,在这里记录一下。

HTTP断点下载相关的报文

  • Accept-Ranges

    告诉客户端服务器是否支持断点续传,服务器返回
  • Content-Range

    在HTTP协议中,响应首部 Content-Range 显示的是一个数据片段在整个文件中的位置。
  • ETag

    资源标识 非必须 服务器返回
  • Last-Modified

    资源最后一次更新的时间 非必须 服务器返回
//响应示例
accept-ranges: bytes
Content-Range: bytes 200-1000/67589 // 返回文件 200字节到1000字节 的数据,总文件大小67589字节
etag: "5f0dce96-48e"
last-modified: Tue, 14 Jul 2020 15:26:14 GMT
  • Range

    请求头设置Range, 指定服务器返回指定区域内容,如果不设置Range会返回整个文件。服务器片段返回状态码是206,请求的范围如果无效状态码会是416,全部返回状态码是200
//示例
Range: bytes=0-499 表示第 0-499 字节范围的内容
Range: bytes=500-999 表示第 500-999 字节范围的内容
Range: bytes=-500 表示最后 500 字节的内容
Range: bytes=500- 表示从第 500 字节开始到文件结束部分的内容
Range: bytes=0-0,-1 表示第一个和最后一个字节
Range: bytes=500-600,601-999 同时指定几个范围

Electron 断点续下载方式

  • 使用 Chromium 的下载功能,在主进程里监听 will-download 事件去处理
  • 使用 Electron 的net模块或者 Node.js 的http/https模块自己创建请求,记录已下载位置

使用 Chromium 的下载

可以在渲染进程中和网页一样进行触发下载(例如a标签),也可以在主进程中使用 BrowserWindow.webContents 或 session 的 downloadURL触发下载

//示例

//使用窗体 创建下载事件和监听
let win = new BrowserWindow()
win.webContents.downloadURL(url)
win.webContents.session.on('will-download', (event, downloadItem, webContents) => {
event.preventDefault()//可以阻止下载
//downloadItem 下载项目的 EventEmitter
}) //或者 使用默认session对象。
session.defaultSession.downloadURL(url)
session.defaultSession.on('will-download', (event, downloadItem, webContents) => { })

然后可以 will-download 事件中的 downloadItem 实例去存储下载信息。等待程序再次启动时通过 session.createInterruptedDownload 恢复上一次的下载

大致流程

//一个简易示例
let cacheItem = {}
session.defaultSession.on('will-download', (e, item) => {
const url = item.getURL() // 获取文件的总大小
const totalBytes = item.getTotalBytes();
// 设置下载路径
const filePath = path.join(app.getPath("downloads"), item.getFilename());
item.setSavePath(filePath); // 缓存downitem 将这些信息保存下来,
cacheItem.path = item.getSavePath();//图片地址
cacheItem.eTag = item.getETag();//资源标识
cacheItem.urlChain = item.getURLChain();//地址
cacheItem.length = totalBytes//资源大小
cacheItem.lastModified = item.getLastModifiedTime()//资源最后一次更新的时间
cacheItem.startTime = item.getStartTime(); let lastBytes = 0; // 监听下载过程,计算并设置进度条进度
item.on('updated', (event, state) => {
if (state === 'interrupted') {
console.log('下载已经中断,可以恢复')
} else if (state === 'progressing') {
if (item.isPaused()) {
console.log('暂停下载')
} else {
let offset = item.getReceivedBytes();
cacheItem.speedBytes = offset - lastBytes;//下载速度
cacheItem.offset = offset//已经下载
lastBytes = offset
console.log('下载中')
}
}
}) //
item.once('done', (event, state) => {
if (state === 'interrupted') {
console.log('下载已经中断,无法恢复')
}
else if (state === 'cancelle') {
console.log('下载取消')
}
else {
console.log('下载完成')
}
}) //是否可恢复下载
if (item.canResume) {
item.resume()
}
})
//程序关闭时将 cacheItem 存储下载 // ===> 程序 再次打开时 // 将上面存储cacheItem信息读取出来 恢复下载
session.defaultSession.createInterruptedDownload({
path,
urlChain,
offset, // 下载断点开始位置
length,
lastModified, //
eTag, //
startTime
})

相关的文档地址 BrowserWindow ,Session , webContents, DownloadItem

创建请求实现续下载

大致上和上面是差不多的,记录已下载文件信息,再次请求时候设置从指定位置开始请求数据

Electron 的断点续下载的更多相关文章

  1. curl断点续载

    摘自http://blog.csdn.net/zmy12007/article/details/37157297 摘自http://www.linuxidc.com/Linux/2014-10/107 ...

  2. 关于视频断点续播和H5的本地存储

    前段时间,需要在下实现一个视频的断点续播功能,呃,我不会呀,这就很尴尬了.然后呢,在下就想起了一个叫做localStorage的东西.这是个什么东西呢?在网上查阅了一些资料后,在下发现这是webSto ...

  3. scrapy爬虫之断点续爬和多个spider同时爬取

    from scrapy.commands import ScrapyCommand from scrapy.utils.project import get_project_settings #断点续 ...

  4. python3.6 单文件爬虫 断点续存 普通版 文件续存方式

    # 导入必备的包 # 本文爬取的是顶点小说中的完美世界为列.文中的aa.text,bb.text为自己创建的text文件 import requests from bs4 import Beautif ...

  5. python下载mp4 同步和异步下载支持断点续下

    Range 用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式: Range:(unit=first byte pos)-[last byte pos] Range 头部的格式有以下几种 ...

  6. vue+uniapp实现多任务并发下载文件 | 断点续下, 任务列表, 多任务并发限制

    一.插件简介 zhimi-downloadManager(智密 - 多任务下载管理插件)是一个支持多任务多并发下载,支持多/单任务管理,并且实时反馈任务下载进度的uniapp原生插件.平台支持:And ...

  7. iOS-网络编程(二)文件上传和断点离线下载

    一. iOS中发送HTTP请求的方案 在iOS中,我们常用发送HTTP请求的方案有苹果原生(自带)NSURLConnection:用法简单,最古老最经典最直接的一种方案 (iOS 9.0弃用)NSUR ...

  8. HTML 5 断点续上传

    断点上传,java里面比较靠谱一点的,一般都会选用Flex.我承认,Flex只是摸了一下,不精通.HTML 5 有个Blob对象(File对象继承它),这个对象有个方法slice方法,可以对一个文件进 ...

  9. Keras模型训练的断点续训、早停、效果可视化

    训练:model.fit()函数 fit(x=None, y=None, batch_size=None, epochs=, verbose=, callbacks=None, validation_ ...

随机推荐

  1. 如何修改或新增visual studio 的模板

    在 visual studio 中添加模板,我这里是新增mvc.net的模板 vs2017在文件夹=>(举例说明,请替换为相应的安装目录) D:\Program Files (x86)\Micr ...

  2. MeteoInfoLab脚本示例:风场矢量图

    读取风场U/V变量数据,可以从U/V计算出风速:speed = sqrt(u*u+v*v).quiverm函数用来绘制风场矢量图,参数中包括U/V变量,如果要绘制彩色风场还需要第三个变量,这里是风速s ...

  3. spring boot:spring security用mysql实现动态权限管理(spring boot 2.3.3)

    一,动态权限管理的优点和缺点 1,优点: 因为控制权限的数据保存在了mysql或其他存储系统中, 可以动态修改权限控制,无需改动代码和重启应用,  权限变更时灵活方便 2,缺点: 权限的设置需要保存在 ...

  4. MS SQL SERVER执行大脚本文件时,提示“内存不足”的解决办法

    问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是当数据库导出脚本很大,用Microsoft SQL Server Management Studio执行 ...

  5. Helium文档13-WebUI自动化-helium快速切换到selenium状态并调用其方法

    前言 前面说过helium是对Selenium 进行了封装,那么我们如何使用selenium的方法呢,通过下面的介绍,我们能够清楚在helium中能够使用selenium的任何方法 入参介绍 def ...

  6. Linux文件的查找之find命令处理动作

    查找到文件之后的处理动作 例如:找出来系统中比较大超过10G的并且存放时间超过一年的log文件并删除 find / -name ".log" -size +10G -mtime + ...

  7. Java中的String到底占用多大的内存空间?你所了解的可能都是错误的!!

    写在前面 最近小伙伴加群时,我总是问一个问题:Java中的String类占用多大的内存空间?很多小伙伴的回答着实让我哭笑不得,有说不占空间的,有说1个字节的,有说2个字节的,有说3个字节的,有说不知道 ...

  8. Docker知识总结

    目录 1 安装docker 2 docker基本概念 2.1 Docker是容器化平台 2.2 Docker体系结构 2.3 容器与镜像 3 docker常用命令 3.1 快速安装tomcat 3.1 ...

  9. 最新版Python 3.8.6 版本发布

    Python 3.8.6 发布了,它是 Python 3.8 的第六个维护版本. 3.8 系列的维护版本将每两个月定期更新一次,3.8.7 计划于 2020 年 11 月中旬发布. 随着维护版本的发布 ...

  10. 如何解决json返回的乱码

    方法一: 通过@RequestMaping的produces属性来实现,修改下代码 //produces:指定响应体返回类型和编码@RequestMapping(value = "/xxx& ...