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();

    }

});

这是为什么?


4 回复

问题分析

错误 Error: MultipartParser.end(): stream ended unexpectedly: state = START_BOUNDARY 通常发生在处理文件上传时,MultipartParser 解析器在预期之外的位置遇到了流的结束。这可能是由于请求被意外中断、文件上传不完整或者解析器状态管理出现问题。

可能的原因

  1. 客户端请求中断:用户可能在文件上传过程中取消了请求。
  2. 服务器端限制:服务器可能因为超时或其他限制而提前关闭连接。
  3. 文件大小超出限制:如果文件过大,可能会导致流提前结束。
  4. 编码问题:如果文件或表单数据使用了不正确的编码方式,也可能导致解析失败。

示例代码修正

为了更好地处理这种情况,我们可以增加一些错误处理逻辑,并确保文件上传过程中的所有情况都被妥善处理。以下是改进后的代码:

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解析出错!!!

相关资料 http://cnodejs.org/topic/50234890f767cc9a51f88481

你遇到的错误 Error: MultipartParser.end(): stream ended unexpectedly: state = START_BOUNDARY 通常是因为文件上传流被意外中断了。这可能是由于请求被提前终止、文件过大或网络问题等原因引起的。

以下是一些可能的解决方案:

  1. 确保请求完整:确保客户端在上传文件时没有提前关闭连接。
  2. 增加超时时间:如果上传文件较大,可以尝试增加请求处理的超时时间。
  3. 检查文件大小限制:确保服务器端配置允许上传大文件。

示例代码中增加超时时间和确保文件完整性:

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,以避免处理空文件。

这些更改应该能帮助你解决文件上传时出现的错误。如果问题仍然存在,建议检查客户端发送请求的行为,确保文件上传过程中没有提前中断。

回到顶部