How to store a file with file extension with multer?

后端 未结 11 1599
情话喂你
情话喂你 2020-12-13 17:56

Managed to store my files in a folder but they store without the file extension.

Does any one know how would I store the file with file extension?

相关标签:
11条回答
  • 2020-12-13 18:29

    An object oriented way to store image with unique name

    // image.service.ts
    import { diskStorage, StorageEngine } from "multer";
    
    class ImageStorageService {
    
        storage: StorageEngine
        constructor() {
            const MIME_TYPE_MAP = {
                'image/png': 'png',
                'image/jpeg': 'jpg',
                'image/jpg': 'jpg'
            }
    
            this.storage = diskStorage({
                destination: (req, file, callback) => {
                    const isValid = MIME_TYPE_MAP[file.mimetype]
                    let error = new Error(`Invalid mime type`)
                    if (isValid)
                        error = null
    
                    //app.use(express.static(path.join(`${__dirname}/assets`)))
                    callback(error, 'assets/images')
                },
                filename: (req, file, callback) => {
                    let currentFileName: string = file.originalname.substr(0, file.originalname.lastIndexOf('.'))
                    const name = currentFileName.toLowerCase().split(' ').join('-')
                    const ext = MIME_TYPE_MAP[file.mimetype]
                    callback(null, `${name}-${Date.now()}.${ext}`)
                }
            })
        }
    }
    
    export const ImageStorage = new ImageStorageService().storage
    

    then in one of your routes

    import { ImageStorage } from "./services/image-storage.service";
    
    this.router.post('/signup', multer({ storage: ImageStorage }).single('image'), async (req, res, next) => {
        let img_url: string
        if (req.file) {
            const url: string = `${req.protocol}:\/\/${req.get('host')}`
            img_url = url + '/images/' + req.file.filename
            //http://localhost:3000/images/penguins-1548339248380.jpg
        }
    })
    
    0 讨论(0)
  • 2020-12-13 18:30

    The file extension can be dynamic. here is the solution

    const path = require('path'); // path for cut the file extension
    const storage = multer.diskStorage({
        destination: function (req, file, cb) {
          cb(null, 'uploads')
        },
        filename: function (req, file, cb) {
          cb(null, 'upload_at_' + Date.now() + path.extname(file.originalname))
        }
      })
    
    0 讨论(0)
  • 2020-12-13 18:33

    I used this little trick to get file extension, and as a workaround to circumvent issues that might occur when someone uploads a file with similar file name twice, or that exists in the server.

    const path = require('path');
    const crypto = require('crypto');
    
    let upload = multer({
    storage: multer.diskStorage({
        destination: (req, file, cb) => {
            cb(null, path.join(__dirname, '../uploads'))
        },
        filename: (req, file, cb) => {
            // randomBytes function will generate a random name
            let customFileName = crypto.randomBytes(18).toString('hex')
            // get file extension from original file name
            let fileExtension = path.extname(file.originalname).split('.')[1];
            cb(null, customFileName + '.' + fileExtension)
        }
      })
    })
    
    0 讨论(0)
  • 2020-12-13 18:34

    In 2018, it is done done like this:

    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, config.DIR)
        },
        filename: function (req, file, cb) {
            let ext = file.originalname.substring(file.originalname.lastIndexOf('.'), file.originalname.length);
            cb(null, Date.now() + ext)
        }
    });
    const upload = multer({
        storage: storage
    }).any();
    
    0 讨论(0)
  • 2020-12-13 18:34

    There may be some issues in the already answered codes.

    • There may be some cases of files with no extension.
    • There should not be an upload.any() usage. Its vulnerable to the attackers
    • The upload function should not be global .

    I have written the below codes for better security.

    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
    
            cb(null, 'temp/')
        },
        filename: function (req, file, cb) {
            let ext = ''; // set default extension (if any)
            if (file.originalname.split(".").length>1) // checking if there is an extension or not.
                ext = file.originalname.substring(file.originalname.lastIndexOf('.'), file.originalname.length);
            cb(null, Date.now() + ext)
        }
    })
    var upload = multer({ storage: storage });
    

    Using it for upload

    // using only single file object name (HTML name attribute)
    // May use upload.array(["file1","file2"]) for more than one
    app.post('/file_upload', upload.single("file"), function (req,res) {
        //console.log(req.body, 'Body');
        console.log(req.file, 'file');
        res.send("cool");
    })
    
    0 讨论(0)
提交回复
热议问题