node.js 如何使用multer存储具有文件扩展名的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31592726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to store a file with file extension with multer?
提问by user3355603
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?
有谁知道我将如何存储带有文件扩展名的文件?
回答by srijishks
I have a workaround for the adding proper extension of files. If you use pathnode module
我有一个解决方法来添加适当的文件扩展名。如果您使用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 });
回答by Scott
From the docs: "Multer will not append any file extension for you, your function should return a filename complete with an file extension."
来自文档:“Multer 不会为您附加任何文件扩展名,您的函数应该返回一个完整的文件名和文件扩展名。”
Here's how you can add the extension:
以下是添加扩展的方法:
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 });
I would recommend using the mimetypeproperty to determine the extension. For example:
我建议使用该mimetype属性来确定扩展名。例如:
filename: function (req, file, cb) {
console.log(file.mimetype); //Will return something like: image/jpeg
More info: https://github.com/expressjs/multer
回答by VISHNU Radhakrishnan
I got file the extension from file.mimetype.
I split the mimetype and get the file extension from it
Please try the below function.
我从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 })
回答by Zohaib Aslam
In 2018, it is done done like this:
在 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();
回答by Danny Sofftie
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)
}
})
})
回答by m.e.conroy
import multer from 'multer';
import * as shortid from 'shortid';
import * as mime from 'mime-types';
const storage = multer.diskStorage({
destination: function (req,file,cb) {
cb(null, '/path/to/uploads/');
},
filename: function (req,file,cb) {
/* generates a "unique" name - not collision proof but unique enough for small sized applications */
let id = shortid.generate();
/* need to use the file's mimetype because the file name may not have an extension at all */
let ext = mime.extension(file.mimetype);
cb(null, `${id}.${ext}`);
}
});
回答by Durgesh Satyam
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.
- 可能有一些文件没有扩展名的情况。
- 不应该有
upload.any()用法。它容易受到攻击者的攻击 - 上传功能不应该是全局的。
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");
})
回答by WasiF
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
}
})
回答by NewUser
I am doing like this
我这样做
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');

