Nodejs 关于formidable获取上传文件的tmp缓存文件

Nodejs 关于formidable获取上传文件的tmp缓存文件

本人使用formidable上传文件,重写了"form.onPart = function(part) {}", github上说"You may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any ‘field’ / ‘file’ events processing which would occur otherwise, making you fully responsible for handling the processing."因此无法使用’field’/‘file’,请问有其他方式能获取得到吗?


2 回复

当然可以。在使用 formidable 处理文件上传时,如果你重写了 form.onPart 方法,确实会禁用默认的 fieldfile 事件处理。但是,你仍然可以通过直接访问 part 对象来处理上传的文件。

下面是一个示例代码,展示如何通过 form.onPart 方法获取上传文件的临时缓存文件路径,并将其保存到指定目录:

const http = require('http');
const formidable = require('formidable');

http.createServer((req, res) => {
    if (req.url === '/upload' && req.method.toLowerCase() === 'post') {
        const form = new formidable.IncomingForm();
        
        form.uploadDir = './uploads'; // 设置文件上传的目录
        
        form.onPart = function (part) {
            if (!part.filename) {
                // 如果不是文件部分,则继续默认处理
                form.handlePart(part);
            } else {
                // 获取临时文件路径
                const tempFilePath = part.filepath;
                
                // 自定义处理逻辑,例如将文件移动到指定目录
                const newPath = `${form.uploadDir}/${part.filename}`;
                fs.rename(tempFilePath, newPath, (err) => {
                    if (err) {
                        console.error('Error moving file:', err);
                        res.writeHead(500);
                        res.end('Internal Server Error');
                        return;
                    }
                    res.writeHead(200);
                    res.end('File uploaded successfully');
                });
            }
        };

        form.parse(req, (err, fields, files) => {
            if (err) {
                console.error('Error parsing form:', err);
                res.writeHead(400);
                res.end('Bad Request');
                return;
            }

            res.writeHead(200);
            res.end('File received and processed successfully');
        });
    } else {
        res.writeHead(200);
        res.end('Upload a file by POST request to /upload');
    }
}).listen(3000, () => {
    console.log('Server running at http://localhost:3000/');
});

解释

  1. 设置上传目录

    form.uploadDir = './uploads';
    

    这行代码设置了文件上传的目录,formidable 会将上传的文件先存储在临时位置,然后你可以根据需要进行处理。

  2. 重写 form.onPart 方法

    form.onPart = function (part) {
        if (!part.filename) {
            form.handlePart(part);
        } else {
            const tempFilePath = part.filepath;
            const newPath = `${form.uploadDir}/${part.filename}`;
            fs.rename(tempFilePath, newPath, (err) => {
                if (err) {
                    console.error('Error moving file:', err);
                    res.writeHead(500);
                    res.end('Internal Server Error');
                    return;
                }
                res.writeHead(200);
                res.end('File uploaded successfully');
            });
        }
    };
    

    在这个方法中,我们检查是否是文件部分。如果是文件部分,我们获取临时文件路径 part.filepath,并将其移动到指定的上传目录。如果不是文件部分,则调用 form.handlePart(part) 继续默认处理。

通过这种方式,即使你重写了 form.onPart 方法,也可以灵活地处理上传的文件。


在使用 formidable 处理文件上传时,如果你重写了 form.onPart 方法来直接访问多部分流(multipart stream),那么默认的 fieldfile 事件将不会被触发。不过,你可以通过检查 part.filename 来判断当前处理的部分是否为文件,并且可以通过读取临时文件的方式来获取上传的文件内容。

下面是一个简单的示例代码,展示了如何在重写 onPart 方法的情况下获取上传文件的临时缓存文件路径:

const formidable = require('formidable');
const fs = require('fs');

function handleUpload(req, res) {
    const form = new formidable.IncomingForm();

    form.onPart = function (part) {
        if (part.filename) { // 判断是否为文件
            // 设置自定义处理逻辑
            this.handlePart(part);
        } else {
            // 处理表单字段
            form.handlePart(part);
        }
    };

    form.parse(req, function(err, fields, files) {
        if (err) {
            return res.status(500).send({ error: 'File upload failed' });
        }

        // 获取临时文件路径
        const tmpFilePath = files.yourFieldName.path;
        console.log(`Temporary file path: ${tmpFilePath}`);

        // 可以选择将临时文件移动到指定位置或进行其他处理
        fs.rename(tmpFilePath, 'new/path/to/save/' + files.yourFieldName.name, err => {
            if (err) {
                return res.status(500).send({ error: 'Failed to move temporary file' });
            }
            res.send({ success: 'File uploaded successfully' });
        });
    });
}

// 示例请求处理
app.post('/upload', handleUpload);

解释:

  1. form.onPart 方法用于处理多部分数据。我们检查 part.filename 来判断当前部分是否为文件。
  2. 如果是文件,则调用 this.handlePart(part) 继续处理。
  3. 使用 form.parse() 解析请求,当遇到错误时返回错误信息。
  4. files 对象中获取临时文件路径 tmpFilePath
  5. 可以使用 fs.rename() 将临时文件移动到其他位置,或者进行其他处理。

这种方式允许你在不依赖默认 fieldfile 事件的情况下,仍然能够访问上传文件的临时缓存文件。

回到顶部