electron打包后主进程下载文件崩溃

electron+vue3写了一个小项目,实现了一个文件下载功能

存在的问题

复制代码
	打包后,应用下载文件崩溃

代码

javascript 复制代码
// 渲染进程
 window.electron.ipcRenderer.invoke(
      'save-file', {
        'path': r.filePath,
        'fileurl': previewUrl,
      }
    ).then(response => {
      console.log('response --------------');
      console.log(response);
    })


// 主进程
ipcMain.handle('save-file', (event, args) => {
  // process.crash()
  try {
    // 下载保存文件
    console.log('axios args.fileurl ------------');
    console.log(args.fileurl);
    return downloadFile(args.fileurl, args.path)
  } catch (error) {
    console.log('error ---------------------------')
    console.log(error)
    return 'save-file 出错了: \n' + error.toString()
  }
});


// 工具文件
import axios from 'axios'
import fs from 'fs/promises'

export function downloadFile(downloadUrl, downloadPath) {
  try {
    return axios.get(downloadUrl, {
      method: 'GET',
      headers: {
          "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36",
          "Referer": downloadUrl,
      },
      responseType: 'arraybuffer'
    }).then(res => {
      console.log('下载成功')
      return fs.writeFile(downloadPath, res.data, "binary").then(r => {
        console.log('保存成功')
        return fs.stat(downloadPath)
      });
    }).catch(e => {
      console.log('e ------------------')
      console.log(e)
      return e
    });
  } catch (error) {
    console.log('error ---------------------------')
    console.log(error)
    return 'downloadFile 出错了: \n' + error.toString()
  }
}

解决思路

首先,要复现,我测试了自己的笔记本电脑,双系统都没问题,没办法复现这个bug,但是测试那边两台电脑都能复现,测试是在外地!我只好又找了一台闲置电脑,还好复现出来了,否则只能回家试试自己的电脑了

第二,找到问题所在,打包后 console.log 就看不到了,我想办法记录日志,看了官方的crashReporter,还有不少人推荐,我正好全栈,就搞了个接口接收日志,但是没有任何报错。后来试了electron-log,记录在用户本地,真香,简单好用,以后有需要直接搞个接口上传log文件就好了!还是没报错!但是我锁定了有问题的那一行代码,就是 axios.get(downloadUrl, { 这里崩溃的!

第三,想办法换掉axios!试了第三方electron下载库,electron-download、electron-dl、都很难用,文档少,搜索结果更少,自己摸索半天也没跑起来,继续换electron-download-manage,但是这个东西调用很麻烦!换request下载,和axios比较像,还是不行!我觉得我的方向可能错了,灵机一动,把axios下载放在渲染进程里面,下载好的数据传递给主进程!好了!

代码

javascript 复制代码
// 渲染进程
    axios.get(previewUrl, {
      method: 'GET',
      responseType: 'arraybuffer'
    }).then(res => {
      console.log('下载成功')
      console.log('下载成功')
      console.log('下载成功')
      console.log(typeof res.data)
      window.electron.ipcRenderer.invoke(
        'save-file', {
          'data': res.data,
          'path': r.filePath,
        }
      ).then(response => {
        console.log('response --------------');
        console.log(response);
      })


// 主进程

ipcMain.handle('save-file', (event, args) => {
  try {
    log.info('event, args ------------');
    log.info(event, args);
    // 保存文件
    return saveFile(args.data, args.path)
  } catch (error) {
    log.info('error ---------------------------')
    log.info(error)
    return 'save-file 出错了: \n' + error.toString()
  }
});

// 工具js
import fs from 'fs/promises'
import log from 'electron-log'
import { Buffer } from 'buffer'

export function saveFile(data, downloadPath) {
  log.info('saveFile ----------------------- 0')
  try {
    log.info('saveFile ----------------------- 1')
    return fs.writeFile(downloadPath, Buffer.from(data), "binary").then(r => {
      log.info('保存成功')
      return fs.stat(downloadPath)
    });
  } catch (error) {
    log.info('saveFile ----------------------- 3')
    log.info('error ---------------------------')
    log.info(error)
    throw new Error('saveFile出错了:' + error.toString()) // 将错误包装成新的Error对象并抛出,让调用者知道发生了错误
  }
}

中间还发生了一个小插曲

复制代码
Error occurred in handler for 'save-file': 
TypeError [ERR_INVALID_ARG_TYPE]: 
The "data" argument must be of type string or an instance of 
Buffer, TypedArray, or DataView. Received an instance of ArrayBuffer

所以才有了Buffer.from(data)

感谢文心一言,感谢我自己!

相关推荐
不可能片场3 小时前
工程实践 台账备份从全量复制改成增量日志
前端·electron
林恒smileZAZ8 小时前
用 Vue 3 + Electron 做桌宠:从启动退出到拖拽、单击与鼠标穿透
vue.js·electron·计算机外设
非常好吃的糖1 天前
Windows 桌面端的语音唤醒:从「识别出文字」到「识别出唤醒词」
electron
Suprman2 天前
从 B/S 到 Electron:平面排版套料系统桌面版开发实战
javascript·平面·electron·排序算法
不可能片场4 天前
工程实践 一个缓存把选片从十分钟压到一分钟
前端·electron
lemon_sjdk5 天前
从一段真实的 Electron IM 前端代码,看高级前端的工程化修养
前端·electron·状态模式·im
优选资源分享6 天前
PicGo v3.0.3 新版 | 开源免费图床工具
javascript·笔记·electron
不可能片场6 天前
Electron 发布核验 别把没查到当成没发出去
前端·electron
flash俊杰6 天前
桌宠点击反应:把一坨 if 拆成「归一化 → 门控查表 → 执行 → 广播」
electron
日耗10亿Token被老板赶出门8 天前
REA 火了:一个 Electron 按钮的调用链,它能追到哪一步?
javascript·electron