В прошлой теме при загрузке имени файла присваивается некоторое произвольное значение. Тем не менее, возможно, нас такие имена файлов не устраивают, и мы хотим сами контроллировать процесс именования файлов. В этом случае мы можем выполнить более точную настройку multer:
const express = require("express"); const multer = require("multer"); const app = express(); const storageConfig = multer.diskStorage({ destination: (req, file, cb) =>{ cb(null, "uploads"); }, filename: (req, file, cb) =>{ cb(null, file.originalname); } }); app.use(express.static(__dirname)); app.use(multer({storage:storageConfig}).single("filedata")); app.post("/upload", function (req, res, next) { let filedata = req.file; if(!filedata) res.send("Ошибка при загрузке файла"); else res.send("Файл загружен"); }); app.listen(3000, ()=>{console.log("Server started");});
Для настройки сохранения файлов применяется функция multer.diskStorage()
. Она принимает объект с двумя параметрами, каждый из которых представляет функцию:
destination
: определяет место для сохранения загруженных файлов - в данном случае папка "uploads".
filename
: определяет имя для загруженных файлов - в данном случае это непосредственно имя загруженного файла - file.originalname
.
Хотя здесь при необходимости можно использовать другие методы, например, добавить к имени файла текущую дату:
filename: function (req, file, cb) { cb(null, file.originalname + "-" + Date.now()) }
Оба параметра получаю объект запроса req
, из которого при необходимости мы можем получить какие-то другие данные запроса и использовать их при сохранении файла.
Затем необходимо установить параметр storage:
app.use(multer({storage:storageConfig}).single("filedata"));
При сохранении файлов мы можем столкнуться с необходимостью их фильтрации по типу. Возможно, нам нужны только файлы изображений или файлы pdf или какие-то другие типы файлов. В этом случае мы можем определить фильтр. Например, будем принимать только файлы изображений:
const express = require("express"); const multer = require("multer"); const app = express(); const storageConfig = multer.diskStorage({ destination: (req, file, cb) =>{ cb(null, "uploads"); }, filename: (req, file, cb) =>{ cb(null, file.originalname); } }); // определение фильтра const fileFilter = (req, file, cb) => { if(file.mimetype === "image/png" || file.mimetype === "image/jpg"|| file.mimetype === "image/jpeg"){ cb(null, true); } else{ cb(null, false); } } app.use(express.static(__dirname)); app.use(multer({storage:storageConfig, fileFilter: fileFilter}).single("filedata")); app.post("/upload", function (req, res, next) { let filedata = req.file; console.log(filedata); if(!filedata) res.send("Ошибка при загрузке файла"); else res.send("Файл загружен"); }); app.listen(3000, ()=>{console.log("Server started");});
Фильтр фактически представляет функцию, которая принимает три параметра: req
(объект запроса), file
(загруженный файл) и
функция cb()
:
const fileFilter = (req, file, cb) => { if(file.mimetype === "image/png" || file.mimetype === "image/jpg"|| file.mimetype === "image/jpeg"){ cb(null, true); } else{ cb(null, false); } }
С помощью значения file.mimetype
мы можем проверить MIME-тип файла. Далее вызывается функция cb()
. Если MIME-тип подходит, то есть
мы хотим сохранить данный файл, то в качестве второго параметра в функцию cb передается true
. Если же мы хотим отклонить файл, то передается значение
false
.
Когда выполняется вызов cb(null, false)
, то при получении multer не устанавливает значение req.file
, то есть фактически оно равно undefined.
Соответственно эту ситуацию мы можем обработать при получении запроса:
app.post("/upload", function (req, res, next) { let filedata = req.file; if(!filedata) res.send("Ошибка при загрузке файла");
И чтобы применить данный фильтр, его необходимо передать в объект multer параметру fileFilter:
app.use(multer({storage:storageConfig, fileFilter: fileFilter}).single("filedata"));