首页 > 解决方案 > 使用表单数据和 axios 从渲染器进程上传电子文件

问题描述

我正在尝试从电子应用程序的渲染过程中以编程方式上传文件(和一些字段)。为此,我正在使用 form-data 和 axios 包。

代码是 TypeScript,最简单的形式如下:

import axios from 'axios';
import fs from 'fs';
import FormData from 'form-data';

function upload(url: string, file: string, additionalFieldValue: string): void {
  const f = new FormData();
  f.append('additionalField', additionalFieldValue);
  f.append(file, fs.createReadStream(file));
  axios.post(url, f, {
    headers: f.getHeaders(),
  });
}

我遇到的问题是它f始终是本机FormData对象,而不是 包FormData中声明的类型的对象form-data。因此,它会产生TypeError: f.getHeaders is not a function错误。

如果我将import语句更改为:

import SomeFormDataThatIsNotNative from 'form-data';

或者如果我尝试使用别名:

import * as SomeFormDataThatIsNotNative from 'form-data';

并调用构造函数,如:

   const f = new SomeFormDataThatIsNotNative();

我需要帮助理解为什么实例化一种类型的对象(FormDataform-data包中声明)会导致不同类型的对象(本机FormData)。我究竟做错了什么?我必须在主进程中移动代码吗?在渲染器过程中会发生什么?

标签: javascripttypescriptaxioselectronform-data

解决方案


这不是真正的解决方案,更像是一种解决方法,但它确实有效。

我已将upload函数从渲染器进程移至主进程。这会将上下文从在浏览器中运行更改为在 Node 下运行。

upload在渲染器过程中,我已将


import { ipcRenderer } from 'electron';

async function upload(url: string, file: string, additionalFieldValue: string) {
  return ipcRenderer('upload', url, file, additionalFieldValue);
}

在主要过程中,我添加了以下内容:

import axios from 'axios';
import FormData from 'form-data';
import { ipcMain } from 'electron';

ipcMain.handle('upload', async (event, url, file, additionalFieldValue) => {
  const f = new FormData();
  f.append('additionaField', additionalFieldValue);
  f.append(file, fs.createReadStream(file));
  return axios.post(url, f, {
    headers: f.getHeaders(),
  });
});

我仍然想了解为什么它不能仅与渲染器进程中的代码一起使用,但现在,我可以继续前进。


推荐阅读