Electron中的下载方案

2,767 阅读2分钟

1、简单下载

通过a标签或者iframe实现下载,缺点是必须先将文件下载完成后才会弹出保存弹窗,适用于小文件下载保存(图片保存等)

export const download = (url, fileName = "") => {
  if (!fileName) {
    fileName = url.substring(url.lastIndexOf("/") + 1);
  }
  // 创建一个<a>标签
  const element = document.createElement("a");
  // 设置href属性为下载链接
  element.setAttribute("href", url);
  // 设置download属性为文件名
  element.setAttribute("download", fileName);
  // 将<a>标签添加到DOM中
  document.body.appendChild(element);
  // 模拟点击<a>标签开始下载
  element.click();
  // 从DOM中移除<a>标签
  document.body.removeChild(element);
};

2、普通下载

  1. 利用Electron的dialog.showSaveDialogSync方案拿到保存路径 或者 使用默认保存路径
  2. 然后利用axios或者fetch下载文件
  3. 最后使用node的fs写入文件

对比方案1:

  • 优点:可以先选择保存路径再下载,可以处理下载过程中的相关错误
  • 缺点:无法实现暂停下载或者继续下载,无法下载大文件(缓存buffer时有内存上限)

3、高级下载

利用Electron中webContents.downloadURL实现下载方案

  • 优点:自带支持暂停下载,继续下载,取消下载,重新下载,基本符合所有下载场景
 // 在主进程中.
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.webContents.session.on('will-download', (event, item, webContents) => {
  // 无需对话框提示, 直接将文件保存到路径
  item.setSavePath('/tmp/save.pdf')

  item.on('updated', (event, state) => {
    if (state === 'interrupted') {
      console.log('Download is interrupted but can be resumed')
    } else if (state === 'progressing') {
      if (item.isPaused()) {
        console.log('Download is paused')
      } else {
        console.log(`Received bytes: ${item.getReceivedBytes()}`)
      }
    }
  })
  item.once('done', (event, state) => {
    if (state === 'completed') {
      console.log('Download successfully')
    } else {
      console.log(`Download failed: ${state}`)
    }
  })
})
  • 踩坑:will-download在渲染进程中使用时 批量下载可能会导致无法拿到downloadItem.on('done')相关回调,或者出现ipc 通信崩溃(Electron 22)。建议在主进程中使用.
  • 缺点:暂停下载时,退出应用后再启动需要重新下载 无法继续

进阶版下载

解决方案3 退出应用后无法继续下载的问题

  • 通过改造方案2去实现相关需求
  • 在方案2的基础上加入分片下载 response.headers.get('Content-Range'),分片下载可以解决,暂停继续下载功能,结合使用fs.append 追加文件写入。同时利用electron-store将下载进度保存到本地磁盘中可实现退出应用后还可以继续下载

哪种方案最佳

  • 方案3 可实现绝大部分需求 二次封装工作量小
  • 方案4 二次分装工作量较大,功能完善
  • 测试过程中方案4的下载速度比方案3 electron api下载速度快