如何使用multer存储文件扩展名的文件?

时间:2015-07-23 16:11:23

标签: node.js express npm multer

管理将我的文件存储在文件夹中,但它们存储时没有文件扩展名。

有没有人知道我如何用文件扩展名存储文件?

12 个答案:

答案 0 :(得分:50)

我有一个解决方法,可以添加适当的文件扩展名。如果您使用path节点模块

var multer = require('multer');
var path = require('path')

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/')
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + path.extname(file.originalname)) //Appending extension
  }
})

var upload = multer({ storage: storage });

答案 1 :(得分:32)

来自文档:“Multer不会为您附加任何文件扩展名,您的函数应返回带有文件扩展名的文件名。”

以下是添加扩展程序的方法:

var multer = require('multer');

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/')
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '.jpg') //Appending .jpg
  }
})

var upload = multer({ storage: storage });

我建议使用mimetype属性来确定扩展名。例如:

filename: function (req, file, cb) {
  console.log(file.mimetype); //Will return something like: image/jpeg

更多信息:https://github.com/expressjs/multer

答案 2 :(得分:9)

我从file.mimetype获得了扩展名。 我拆分了mimetype并从中获取了文件扩展名 请尝试以下功能。

let storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads')
  },
  filename: function (req, file, cb) {
    let extArray = file.mimetype.split("/");
    let extension = extArray[extArray.length - 1];
    cb(null, file.fieldname + '-' + Date.now()+ '.' +extension)
  }
})
const upload = multer({ storage: storage })

答案 3 :(得分:4)

2018年完成了这样的事情:

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

答案 4 :(得分:3)

我使用了这个小技巧来获取文件扩展名,并作为一种变通方法来避开有人两次上载具有类似文件名的文件或服务器中存在的文件时可能发生的问题。

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 = file.originalname.split('.')[1]
        cb(null, customFileName + '.' + fileExtension)
    }
  })
})

答案 5 :(得分:2)

已经回答的代码可能存在一些问题。

  • 可能会出现没有扩展名的文件的情况。
  • 不应该使用 upload.any() 。它易受攻击者攻击
  • 上传功能不是全局

为了更好的安全性,我编写了以下代码。

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 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");
})

答案 6 :(得分:2)

@Module
public abstract class TestRepoServiceModule {

    @Binds
    abstract RepoService bindRepoService(TestRepoService repoService);
}

答案 7 :(得分:1)

文件扩展名可以是动态的。 这是解决方案

> tibble::glimpse(result)
Rows: 28
Columns: 12
$ Var.1              <chr> "Production", "Imports", "Exports", "International mari...
$ Coal               <int> 3893679, 829289, -879689, NA, NA, -4954, 3838326, -1156...
$ Crude.oil          <int> 4552548, 2479487, -2440069, NA, NA, -6450, 4585516, -23...
$ Oil.products       <int> NA, 1396839, -1488672, NA, NA, 3316, -88517, 261068, 95...
$ Natural.gas        <int> 3293124, 985018, -1019823, NA, NA, 3276, 3261595, NA, -...
$ Nuclear            <int> 706814, NA, NA, NA, NA, NA, 706814, NA, NA, -703393, -3...
$ Hydro              <int> 362332, NA, NA, NA, NA, NA, 362332, NA, NA, -362332, NA...
$ Wind..solar..etc.  <int> 286377, NA, NA, NA, NA, NA, 286377, NA, -42, -233459, -...
$ Biofuels.and.waste <int> 1324214, 29259, -25250, NA, NA, -1096, 1327127, NA, -11...
$ Electricity        <int> NA, 62626, -62373, NA, NA, NA, 253, NA, -5139, 1931734,...
$ Heat               <int> 2062, 6, -2, NA, NA, NA, 2066, NA, 3966, -894, 255095, ...
$ Total              <int> 14421151, 5782524, -5915877, NA, NA, -5909, 14281889, 2...

答案 8 :(得分:0)

我这样做

var multer  = require('multer');

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './public/uploads/img/')
  },
  filename: function (req, file, cb) {
    let ext = file.originalname.substring(file.originalname.lastIndexOf('.'), file.originalname.length);
    cb(null, Date.now() + ext);
  }
})

var upload = multer({ storage: storage }).single('eventimage');

答案 9 :(得分:0)

一种面向对象的方式来存储具有唯一名称的图像

// 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

然后在您的一条路线中

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
    }
})

答案 10 :(得分:0)

我喜欢将原始文件名用于SEO。这需要更多一点检查是否具有相同名称的文件。 此外,扩展解析只需几个步骤即可完成,以提供最大的灵活性。

Library/Developer/CoreSimulator/Profiles/Runtimes

答案 11 :(得分:0)

我使用这种方法并且有效。

我以这种格式存储文件: FieldName+Date+Extension => Profile1621416613594.jpg

var multer = require('multer');
    
var storage = multer.diskStorage({
    destination: function (req,file,cb){
        cb(null, './uploads')
    },
    filename: function (req,file,cb){
        cb(null,file.fieldname+'-'+Date.now()+'.'+file.mimetype.split('/').reverse()[0]);
    },
});

var upload = multer({storage: storage});