正确读取 multipartform-data 流(NodeJS)
Reading multipartform-data stream correctly (NodeJS)
我正在尝试接收可能包含各种文件和字段的多部分数据流,并将文件写入目录(uWebsockets.js 服务器)。
我有这个代码:
let boundary = null;
let fields = [];
let streams = [];
let keep = false;
res.onData((chunk, isLast) => {
const buff = Buffer.concat([Buffer.from(chunk)]).toString('binary').split('\r\n');
if (!boundary) {
boundary = buff[0];
}
for (let i = 0; i < buff.length; i++) {
const line = buff[i];
if (i > 0 && i < buff.length - 1 && line == '') {
keep = true;
continue;
}
if (line == boundary || line == boundary + '--') {
keep = false;
if (streams[fields.length - 1]) {
streams[fields.length - 1].end();
}
}
if (line == boundary) {
fields[fields.length] = {};
}
if (line.includes('Content-Disposition')) {
if (line.includes('filename="')) {
fields[fields.length - 1].filename = getFilename(line);
fields[fields.length - 1].type = 'file';
fields[fields.length - 1].path = path.resolve(options.uploadPath + fields[fields.length - 1].filename);
streams[fields.length - 1] = fs.createWriteStream(
path.resolve(options.uploadPath + fields[fields.length - 1].filename)
);
} else {
fields[fields.length - 1].type = 'field';
}
fields[fields.length - 1].name = getField(line);
}
if (line.includes('Content-Type')) {
fields[fields.length - 1].contentType = line.split('Content-Type: ')[1];
}
if (keep == true) {
if (fields[fields.length - 1].filename) {
streams[streams.length - 1].write(Buffer.from(line + "\r\n", 'binary'));
} else {
fields[fields.length - 1].value += line;
}
}
}
if (isLast) {
console.log(fields);
}
});
除了上传的图片损坏和随机切入外(每张图片都不一样,有些完全损坏,有些完好)。
有人可以指出它有什么问题吗?
提前致谢:)
概率问题是最大长度。在 uwebsocket.js 上更改此值。
最好的方法是上传文件的表单数据。
改变这个:
maxPayloadLength: 512
你试过formidable了吗?
我用它来解析我的 multipartform-data 流。
同样的情况,我正在使用 uwebsocket.js 上传 mp4 文件,我尝试使用您的代码上传 mp4,它已上传但无法播放。然后我尝试比较原始文件和上传的文件,文件大小有一点变化。
然后我在你的代码中意识到:
streams[streams.length - 1].write(Buffer.from(line + "\r\n", 'binary'));
当被“\r\n”拆分时,数组的最后一个不应有“\r\n”
比我在下面添加一些条件:
if (i==buff.length-1)
streams[streams.length - 1].write(Buffer.from(line, 'binary'));
else {
if (i+1<buff.length) {
if (buff[i+1]==boundary + '--')
streams[streams.length - 1].write(Buffer.from(line, 'binary'));
else
streams[streams.length - 1].write(Buffer.from(line + "\r\n", 'binary'));
}
}
现在我上传的 mp4 可以正常播放了。
谢谢....
抱歉我的英语不好
我正在尝试接收可能包含各种文件和字段的多部分数据流,并将文件写入目录(uWebsockets.js 服务器)。 我有这个代码:
let boundary = null;
let fields = [];
let streams = [];
let keep = false;
res.onData((chunk, isLast) => {
const buff = Buffer.concat([Buffer.from(chunk)]).toString('binary').split('\r\n');
if (!boundary) {
boundary = buff[0];
}
for (let i = 0; i < buff.length; i++) {
const line = buff[i];
if (i > 0 && i < buff.length - 1 && line == '') {
keep = true;
continue;
}
if (line == boundary || line == boundary + '--') {
keep = false;
if (streams[fields.length - 1]) {
streams[fields.length - 1].end();
}
}
if (line == boundary) {
fields[fields.length] = {};
}
if (line.includes('Content-Disposition')) {
if (line.includes('filename="')) {
fields[fields.length - 1].filename = getFilename(line);
fields[fields.length - 1].type = 'file';
fields[fields.length - 1].path = path.resolve(options.uploadPath + fields[fields.length - 1].filename);
streams[fields.length - 1] = fs.createWriteStream(
path.resolve(options.uploadPath + fields[fields.length - 1].filename)
);
} else {
fields[fields.length - 1].type = 'field';
}
fields[fields.length - 1].name = getField(line);
}
if (line.includes('Content-Type')) {
fields[fields.length - 1].contentType = line.split('Content-Type: ')[1];
}
if (keep == true) {
if (fields[fields.length - 1].filename) {
streams[streams.length - 1].write(Buffer.from(line + "\r\n", 'binary'));
} else {
fields[fields.length - 1].value += line;
}
}
}
if (isLast) {
console.log(fields);
}
});
除了上传的图片损坏和随机切入外(每张图片都不一样,有些完全损坏,有些完好)。 有人可以指出它有什么问题吗?
提前致谢:)
概率问题是最大长度。在 uwebsocket.js 上更改此值。 最好的方法是上传文件的表单数据。
改变这个:
maxPayloadLength: 512
你试过formidable了吗? 我用它来解析我的 multipartform-data 流。
同样的情况,我正在使用 uwebsocket.js 上传 mp4 文件,我尝试使用您的代码上传 mp4,它已上传但无法播放。然后我尝试比较原始文件和上传的文件,文件大小有一点变化。
然后我在你的代码中意识到:
streams[streams.length - 1].write(Buffer.from(line + "\r\n", 'binary'));
当被“\r\n”拆分时,数组的最后一个不应有“\r\n” 比我在下面添加一些条件:
if (i==buff.length-1)
streams[streams.length - 1].write(Buffer.from(line, 'binary'));
else {
if (i+1<buff.length) {
if (buff[i+1]==boundary + '--')
streams[streams.length - 1].write(Buffer.from(line, 'binary'));
else
streams[streams.length - 1].write(Buffer.from(line + "\r\n", 'binary'));
}
}
现在我上传的 mp4 可以正常播放了。
谢谢....
抱歉我的英语不好