【问题标题】:NodeJS - multer - change filename depending on request attributesNodeJS - multer - 根据请求属性更改文件名
【发布时间】:2019-04-28 10:41:53
【问题描述】:

我知道我可以使用 multer 通过存储对象更改文件名,如下所示:

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, process.env.UPLOAD_DIR);
    },
    filename: (req, file, cb) => {
        cb(null, 'bla.png');
    }
});
const upload = multer({ storage: storage } );

我的请求,除了有文件外,还包含一些文字属性如name: myPic.png

是否可以根据其他请求属性或在控制器内动态更改文件名,如下所示:

filename: (req, file, cb) => {
     cb(null, `${req.body.name}.png`);
}

router.post('/upload', upload.single('pic'), myController.upload);

/* in controller */
upload = async (req: Request, res: Response) => {
    try {

        /* change the filename of multer here? */

    } catch (err) {
        winston.error(`Error while uploading: ${err.message}`);
        winston.error(`Stack trace: ${err.stack}`);
        sendJSONResponse(res, err, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

【问题讨论】:

  • 我遇到了同样的问题,你找到解决办法了吗?

标签: javascript node.js file-upload multer


【解决方案1】:

Multer 是填充req.body 和存储文件的中间件。

此外,当它到达filename() 函数时,不能保证文本字段将填充到req.body,因为它取决于客户端sends them in 的哪个顺序(请参阅最后的注释)。

据我所知,您有两种选择:

1) 在 multer 上传中间件完成其操作并填充 req.bodyreq.file 之后,重命名上传的文件。因此,在您的控制器上传中间件中,您可以执行以下操作:

if (req.file) {
    fs.renameSync(req.file.path, req.file.destination + req.body.name);
}

2) 将请求正文文本字段更改为查询参数。然后,在filename() 中,您可以执行req.query.name

Con:不是一个非常 RESTful 的设计,但也许这对你来说不是那么重要。

【讨论】:

  • 您找到更好的方法了吗?
【解决方案2】:

根据 multer 文档,它无权访问 req.body 以获取其他附加字段,如果您对其进行测试,它会收到 undefined 值,那么一旦文件为上传后可以重命名如下。

  1. 添加本地类 fs 以访问文件选项

    const fs = require('fs');
    
  2. diskStorage配置中添加你想要的名称,例如bla.png

    var storage = multer.diskStorage({
        destination: path.join('public/images/'),
        filename: function ( req, file, cb ) {          
            cb(null, 'bla.png');          
        }
    });
    
  3. 带有自定义名称文本字段的表单

    <form action="/upload" enctype="multipart/form-data" method="POST">
        <input type="file" accept="image/*" name="photo" >
        <br><!--here is the custom file name-->
        <input type="text" name="file_name">
        <br> 
        <button type="submit">Send</button>
    </form>
    
  4. 在帖子路径中,一旦您发送了名称为 bla.png 的文件,您可以通过访问req.body.field_name 将该名称替换为表单字段中的名称

    router.post('/upload', upload.single('photo'), (req, res) => {
        //Here change the file name bla.png for the new value in req.body.field_name + original ext of file
        fs.renameSync(req.file.path, req.file.path.replace('bla.png', 
        req.body.field_name + path.extname(req.file.originalname)));
        if(req.file) { 
            res.json(req.file);
        }
        else throw 'error';
    });
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-18
    • 2019-01-06
    • 2019-12-10
    • 1970-01-01
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多