multipart/form-data 请求失败。串流意外结束

multipart/form-data request failed. Stream ended unexpectedly

我正在将数据从 nodejs 应用程序发送到 spring 休息端点。我按照 form-data to fs.createReadStream from a file, and that's fine. But since my application generates this data, what I actually need is to send the data that's stored in a variable (as a string). So I followed this answer 上的示例从字符串创建流,但在 Java 端我收到 "stream ended unexpectedly" 错误。

var form = new FormData();
form.append('id', id);

// this works
//form.append('inputFiles[]', fs.createReadStream('test.xml'));

//this does not
const Readable = require('stream').Readable;
let s = new Readable();
s._read = () => {};
s.push('some data generated by my application');
s.push(null);

form.append('inputFiles[]', s);

form.submit(url, function(error, result) {
  if (error) {
    console.log('Error!');
  }
});

我需要以某种方式传输这些数据吗?或指定内容长度(如果是这样,我如何确定长度?)我试图将 { filename : 'test.xml', contentType: 'application/xml' } 添加到可读文件中以模仿文件,但仍然出现相同的错误。

我可以建议不同的方法吗?由于您使用的答案是 2014 年...

let form = new FormData();
                form.append('fieldName', 'fileBuffer/DataString', 'fileName');

                axios.post('url', form, {
                    headers: {
                        'Content-Type': `multipart/form-data; boundary=${form._boundary}`
                    }
                }).then((res) => {
                    console.log(res.data);
                    res.json(responseFromServer.data);
                }).catch((err) => {
                    res.status(400).send(err);
                });

以防其他人遇到同样的问题——我需要所有 3 个额外的字段,包括 knownLength

    let stream = new Readable();
    stream.push(foo);
    stream.push(null);
    form.append('inputFiles[]', stream, {
      filename : 'test.xml',
      contentType: 'application/xml',
      knownLength: foo.length
    }); //extra fields necessary

我花了一些时间来找到合适的解决方案,终于解决了。

我知道您实际上需要从缓冲区创建可读文件才能工作。

我创建了一个 class 让这更容易:

const { Readable } = require('stream')

module.exports = class FormData {
  /**
   *
   * @param {string} data The data to be converted
   * @param {string} name The file name
   * @param {string} type The file type
   */
  constructor (data, name, type) {
    const readStream = new Readable();
    readStream._read = () => {}
    readStream.push(Buffer.from(data))
    readStream.push(null)

    return {
      file: {
        value: readStream,
        options: {
          filename: name,
          contentType: type,
          knownLength: data.length,
        }
      }
    }
  }
}

现在,您所要做的就是创建一个实例并用它调用请求函数。

const request = require('request')

const csv = // your csv content

const formData = new FormData(csv, 'conversion.csv', 'text/csv; charset=utf-8')

const options = {// the normal request options (headers etc.)

options.formData = formData

request('https://...', options).then(// your normal request call