Express промежуточное программное обеспечение предназначено для установки на уровне маршрутизации. Действительно, в модели MVC экспресс-программисты называют контроллеры «маршрутами» (лично я переименую их в контроллеры вместо маршрутов в моем коде). Отделение контроллеров от маршрутов (оба они означают одно и то же) не имеет особого смысла, если смотреть на них из традиционных сред MVC, но вы можете, если хотите.
Использовать multer
какразработан вам нужно сделать это в index.router.js
:
index.router.js
const express = require('express');
const router = express.Router();
const multer = require('multer');
const ctrlUpload = require('../controllers/upload.controller');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
cb(null, Date.now()+'-'+file.originalname);
}
});
const upload = multer({ storage });
router.post('/upload', upload.single('img'), ctrlUpload.send);
module.exports = router;
Затем вам нужно удалить всеmulter
связанный код от upload.controller.js
Однако вы можете настаивать на этом в upload.controller.js
. Главное здесь - понять, что такое промежуточное ПО.
В Express промежуточное ПО - это функция с прототипом:
function (req, res, next) { // next is optional
// middleware logic
}
Да, все верно. Код в вашем файле upload.controller.js
является промежуточным ПО. Вы сами пишете промежуточное программное обеспечение, которое оказывается в конце цепочки промежуточного программного обеспечения.
Видите ли, Express принимает только промежуточное программное обеспечение. Экспресс больше ничего не имеет. Маршруты - это промежуточные программы, которые оказываются в конце.
Express .use()
, .get()
, .post()
и связанные методы принимают бесконечное количество аргументов. Первым является необязательный спецификатор маршрута (но не обязательно), а остальные аргументы являются промежуточным программным обеспечением. Например:
app.get('/foo',
(req, res, next) => {
// first middleware
next(); // next is what allows processing to continue
},
(req, res, next) => {
// second middleware
next();
},
(req, res, next) => {
res.send('hello'); // controller logic - a controller
// is just the last middleware
// Note: if you call next() instead of res.send() in a
// controller express will respond with a 500 internal
// server error status with whatever string you pass
// to next() as the error message.
}
);
Зная это, мы знаем, что возвращает функция upload.single('img')
. Функция не выполняет логику промежуточного программного обеспечения . Вместо этого он возвращает функцию промежуточного программного обеспечения:
let middleware = upload.single('img');
// middleware is now a function with the prototype:
// (req, res, next) => {}
Таким образом, чтобы выполнить логику промежуточного программного обеспечения, мы должны вызвать его (Express автоматически вызовет его как часть обработки маршрута, так же, как он вызывает функцию вашего контроллера, но еслимы хотим сделать это сами, мы можем).
Вот что вам нужно сделать, если вы хотите внедрить промежуточное ПО в upload.controller.js
:
module.exports.send = (req, res, next) => {
upload.single('img')(req, res, () => {
// Remember, the middleware will call it's next function
// so we can inject our controller manually as the next()
console.log(req.body, req.files);
res.send('ok');
});
}
Это очень много для распаковки. Мы можем сделать код проще для понимания, если немного его реорганизовать:
let middleware = upload.single('img');
module.exports.send = (req, res, next) => {
// Define the controller here to capture
// req and res in a closure:
let controller = () => {
console.log(req.body, req.files);
res.send('ok');
};
middleware(req, res, controller); // call the middleware with
// our controller as callback
}
Но это очень нестандартно и было бы крайне неожиданно для опытного программиста Express.js. Я бы не стал этого делать, хотя это возможно. Он также тесно связывает промежуточное ПО с вашим контроллером, полностью отрицая очень гибкую природу системы конфигурации промежуточного ПО Express.