Nodejs 文件上传时报错 Error: MultipartParser.end(): stream ended unexpectedly: state = START_BOUNDARY
Nodejs 文件上传时报错 Error: MultipartParser.end(): stream ended unexpectedly: state = START_BOUNDARY
错误提示为:Error: MultipartParser.end(): stream ended unexpectedly: state = START_BOUNDARY
代码为: var form = new formidable.IncomingForm(); form.uploadDir=‘tmp’;
form.parse(request, function(error, fields, files) { if(error) { response.writeHead(500, {“Content-Type”: “text/plain”}); response.write(error + “\n”); response.end(); }else{ console.log(“parsing done : " + files.upload.path); fs.renameSync(files.upload.path, “./tmp/test.png”); response.writeHead(200, {“Content-Type”: “text/html”}); response.write(“received image:<br/>”); response.write(”<img src=’/show’ />"); response.end();
}
});
这是为什么?
问题分析
错误 Error: MultipartParser.end(): stream ended unexpectedly: state = START_BOUNDARY
通常发生在处理文件上传时,MultipartParser 解析器在预期之外的位置遇到了流的结束。这可能是由于请求被意外中断、文件上传不完整或者解析器状态管理出现问题。
可能的原因
- 客户端请求中断:用户可能在文件上传过程中取消了请求。
- 服务器端限制:服务器可能因为超时或其他限制而提前关闭连接。
- 文件大小超出限制:如果文件过大,可能会导致流提前结束。
- 编码问题:如果文件或表单数据使用了不正确的编码方式,也可能导致解析失败。
示例代码修正
为了更好地处理这种情况,我们可以增加一些错误处理逻辑,并确保文件上传过程中的所有情况都被妥善处理。以下是改进后的代码:
const http = require('http');
const formidable = require('formidable');
const fs = require('fs');
http.createServer((req, res) => {
if (req.url === '/upload' && req.method.toLowerCase() === 'post') {
const form = new formidable.IncomingForm();
form.uploadDir = './tmp';
form.parse(req, (err, fields, files) => {
if (err) {
console.error(err);
res.writeHead(500, {"Content-Type": "text/plain"});
res.end("Internal Server Error");
return;
}
console.log("Parsing done: ", files.upload.path);
// Rename the uploaded file to a more permanent location
fs.rename(files.upload.path, "./tmp/test.png", err => {
if (err) {
console.error(err);
res.writeHead(500, {"Content-Type": "text/plain"});
res.end("Failed to move uploaded file");
return;
}
res.writeHead(200, {"Content-Type": "text/html"});
res.write("Received image:<br/>");
res.write("<img src='/show' />");
res.end();
});
});
} else {
res.writeHead(404, {"Content-Type": "text/plain"});
res.end("Not Found");
}
}).listen(3000, () => {
console.log("Server running at http://localhost:3000/");
});
关键点解释
- 错误处理:增加了对
form.parse
中的错误处理,以确保任何错误都能被捕获并响应给客户端。 - 文件重命名:在文件成功上传后,使用
fs.rename
将临时文件移动到永久存储位置,同时处理可能的错误。 - HTTP 状态码:根据不同的情况返回适当的 HTTP 状态码,如
500
表示服务器内部错误,404
表示资源未找到等。
通过这些改进,可以更健壮地处理文件上传过程中可能出现的各种异常情况。
感觉是没有POST文件过去,而是直接访问的 /upload
控制台报错信息: console.log("parsing done : " + files.upload.path); ^ TypeError: Cannot read property ‘path’ of undefined
一行代码引发的悲剧 在文件server.js中不应该用request.setEncoding(“utf8”)来手动设置字符编码, 当设置了这个之后,会导致formidable解析出错!!!
你遇到的错误 Error: MultipartParser.end(): stream ended unexpectedly: state = START_BOUNDARY
通常是因为文件上传流被意外中断了。这可能是由于请求被提前终止、文件过大或网络问题等原因引起的。
以下是一些可能的解决方案:
- 确保请求完整:确保客户端在上传文件时没有提前关闭连接。
- 增加超时时间:如果上传文件较大,可以尝试增加请求处理的超时时间。
- 检查文件大小限制:确保服务器端配置允许上传大文件。
示例代码中增加超时时间和确保文件完整性:
var formidable = require('formidable');
var fs = require('fs');
// 创建表单解析器实例
var form = new formidable.IncomingForm();
// 设置文件上传目录
form.uploadDir = './tmp';
// 增加请求超时时间(例如:60秒)
form.maxFieldsSize = 60 * 1024 * 1024;
// 解析请求中的表单数据
form.parse(request, function(error, fields, files) {
if (error) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(error + "\n");
response.end();
} else {
console.log("parsing done : " + files.upload.path);
// 检查文件是否完整上传
if (files.upload.size > 0) {
fs.renameSync(files.upload.path, "./tmp/test.png");
response.writeHead(200, {"Content-Type": "text/html"});
response.write("received image:<br/>");
response.write("<img src='/show' />");
response.end();
} else {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write("Upload failed: file is empty.\n");
response.end();
}
}
});
解释
- form.maxFieldsSize: 设置请求的最大字段大小(以字节为单位)。这个值可以根据需要调整,以适应更大的文件上传。
- 检查文件大小: 在重命名文件之前,确保文件大小大于0,以避免处理空文件。
这些更改应该能帮助你解决文件上传时出现的错误。如果问题仍然存在,建议检查客户端发送请求的行为,确保文件上传过程中没有提前中断。