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
我正在将数据从 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