Node.js 通过从另一个多部分HTTP请求读取文件来触发HTTP文件上载

Node.js 通过从另一个多部分HTTP请求读取文件来触发HTTP文件上载,node.js,stream,multipartform-data,busboy,nodejs-stream,Node.js,Stream,Multipartform Data,Busboy,Nodejs Stream,上载端点从多部分文件中的客户端接收数据。此文件将再次作为参数发送给来自同一服务的新HTTP调用 //客户端上传文件代码 form(enctype="multipart/form-data", action="/data/upload", method="post") input(type="file", name="data") 我想读取该文件并将其上传到另一个接受该文件的Java端点 我

上载端点从多部分文件中的客户端接收数据。此文件将再次作为参数发送给来自同一服务的新HTTP调用

//客户端上传文件代码

form(enctype="multipart/form-data", action="/data/upload", method="post")
  input(type="file", name="data")

我想读取该文件并将其上传到另一个接受该文件的Java端点

我尝试通过busBoy获取文件流,并将其转换为字符串,然后尝试将字符串转换回流,并将其传递给新请求。但这在Java服务中失败了

import axios from 'axios';

const FormData = require('form-data');
const { Readable } = require('stream');

const fileBufferChunks = [];

busBoyStream.on('file', (fieldname, file, filename, encoding, mimetype) => {
  file.on('data', (data) => {
    fileBufferChunks.push(data);
  });
  file.on('end', () => {
    console.log(` ${filename} file parsed from req`);
    const fileString = Buffer.concat(fileBufferChunks).toString('base64');
    const data = new FormData();
    const readableStream = Readable.from([fileString]);
    data.append('file_param', readableStream);
    const headers = data.getHeaders();
    const axiosConfig = {
      method: 'post',
      url: URL,
      headers: {
        ...headers,
      },
      data,
    };

    axios(axiosConfig)
      .then((response) => {
        console.log('job trigger success');
      });
  });
});
      
但是,如果我将文件存储在本地,并通过fs.createReadStream传递相同的文件流,它就会工作


import axios from 'axios';

const FormData = require('form-data');
const fs = require('fs');

const fileBufferChunks = [];

busBoyStream.on('file', (fieldname: any, file: any, filename: any, encoding: any, mimetype: any) => {
  file.on('end', () => {
    const data = new FormData();
    const saveTo = '/dummypath/name.csv';
    file.pipe(fs.createWriteStream(saveTo));
    data.append('file_param', fs.createReadStream('/dummypath/name.csv'));
    const headers = data.getHeaders();
    const axiosConfig = {
      method: 'post',
      url: URL,
      headers: {
        ...headers,
      },
      data,
    };

    axios(axiosConfig)
      .then((response) => {
        console.log('job trigger success');
      });
  });
});
我想了解将文件转换为字符串并从该文件字符串创建流与使用fs.createReadStream(pathToFile)创建流之间的区别


有人能解释一下为什么行为会有差异,以及从一个HTTP请求向另一个请求发送文件上载的推荐方式吗?

问题在于使用库处理文件属性,该库将流转换为特定于formdata的负载

如果流是由文件流生成的,则库自动填充文件的contentType信息。因此,它可以很好地处理fs文件流。在我的例子中,流是来自流库的可读文件流,所以我需要手动提供contentType信息,如下面的示例所示

data.append(uploadFile.fieldname, uploadFile.file, {
   filename: 'filename.csv', // ... or:
   //   filepath: 
   contentType: 'text/csv',
   // knownLength: 5,
 });
用于处理文件的表单数据库需要为自定义流对象提供许多这样的文件属性。完整的列表可以在他们的网站上找到