多部分/表单数据请求失败。直播意外结束

Posted

技术标签:

【中文标题】多部分/表单数据请求失败。直播意外结束【英文标题】:multipart/form-data request failed. Stream ended unexpectedly 【发布时间】:2019-06-10 20:07:51 【问题描述】:

我正在将数据从 nodejs 应用程序发送到 spring rest 端点。我从文件中按照form-data 到fs.createReadStream 的示例进行操作,这很好。但是由于我的应用程序生成了这些数据,我真正需要的是发送存储在变量中的数据(作为字符串)。所以我按照answer 从字符串创建流,但在 Java 端我收到“流意外结束”错误。

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' 添加到可读文件中以模仿文件,但仍然得到相同的错误。

【问题讨论】:

【参考方案1】:

我可以建议不同的方法吗?由于您使用的答案是 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);
                );

【讨论】:

【参考方案2】:

以防其他人遇到同样的问题——我需要拥有所有 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

【讨论】:

非常感谢。我正在寻找的确切解决方案。我认为 form-data 模块文档没有明确提到 form.append 函数的参数。【参考方案3】:

我花了一些时间为此找到了一个合适的解决方案,终于能够解决它。

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

我创建了一个类来简化此操作:

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

【讨论】:

以上是关于多部分/表单数据请求失败。直播意外结束的主要内容,如果未能解决你的问题,请参考以下文章

多部分/表单数据请求在 react-native 中失败

ASP.NET 5 RC1:System.IO.InvalidDataException:请求内容意外结束

Nodejs POST 请求多部分/表单数据

PHP多部分表单数据PUT请求?

解析多部分/表单数据,从请求后接收

Alamofire 多部分/表单数据上传请求中仅不发送图像