Node.js,穆尔特。视频文件是 saved/uploaded,但验证器给出了视频字段不能保持为空的错误
Node.js, Multer. video file is saved/uploaded but validator gives an error that video field can not remain empty
我正在尝试使用 multer 上传视频,我有一个表单和所有内容,但是当我单击创建时,验证器给出了一个错误,但是文件保存在我的目录中,就好像验证成功一样。
我正在为数据库使用 mongoDB。
这是验证器
const { check } = require('express-validator/check');
const Video = require('app/models/VideoModel');
const path = require('path');
class videoValidator extends validator {
handle() {
return [
check('title')
.isLength({ min : 5 })
.withMessage('title should be at least 5 characters'),
check('artist')
.not().isEmpty()
.withMessage('artist field can not be empty'),
check('videos')
.custom(async (value , { req }) => {
if(req.query._method === 'put' && value === undefined) return;
if(! value)
throw new Error('the video field can not remain empty');
let fileExt = ['.webm' , '.ogg' , '.mp4' , '.avi'];
if(! fileExt.includes(path.extname(value)))
throw new Error('file extention is not supported')
}),
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g , "-")
}
}
module.exports = new videoValidator();
视频控制器
async create(req , res) {
let artists = await Artist.find({});
res.render('admin/videos/create' , { artists });
}
async store(req , res , next) {
try {
let status = await this.validationData(req);
if(! status) return this.back(req,res);
let videos = req.file;
let { title , artist } = req.body;
let newVideo = new Video({
artist,
title,
slug : this.slug(title),
videos,
});
await newVideo.save();
return res.redirect('/admin/videos');
} catch(err) {
next(err);
}
}
路由和上传助手
const videoUpload = require('app/helpers/uploadVideo');
// video Routes
router.get('/videos' , videoController.index);
router.get('/videos/create' , videoController.create);
router.post('/videos/create' ,
videoUpload.single('videos'),
videoValidator.handle(),
videoController.store
);
const multer = require('multer');
const path = require('path');
const mkdirp = require('mkdirp');
const fs = require('fs');
const getDirVideo = () => {
let year = new Date().getFullYear();
let month = new Date().getMonth() + 1;
let day = new Date().getDay();
return `./public/uploads/videos/${year}/${month}/${day}`;
}
const videoStorage = multer.diskStorage({
destination : (req , file , cb) => {
let dir = getDirVideo();
mkdirp(dir , (err) => cb(null , dir))
},
filename : (req , file , cb) => {
let filePath = getDirVideo() + '/' + file.originalname;
if(!fs.existsSync(filePath))
cb(null , file.originalname);
else
cb(null , Date.now() + '-' + file.originalname);
}
})
const uploadVideo = multer({
storage : videoStorage,
limits : {
fileSize : 1024 * 1024 * 40
}
});
module.exports = uploadVideo;
型号和ejs
const videoSchema = Schema({
artist: {
type : Schema.Types.ObjectId,
ref : 'Artist'
},
title: {
type : String,
required : true
},
videos: {
type : Object,
required : true
},
time: {
type: String,
default : '00:00:00'
},
videoUrl: {
type : String,
required : true
},
} , { timestamps : true });
module.exports = mongoose.model('Video' , videoSchema);
<div class="d-flex justify-content-between align-items-center mb-3 pb-2 border-bottom">
<h2>add Video</h2>
</div>
<form class="form-horizontal" action="/admin/videos/create" method="post" enctype="multipart/form-data">
<%- include(viewPath('layouts/error-messages')) -%>
<div class="form-group row">
<div class="col">
<label for="title" class="control-label font-weight-bold">Video Title </label>
<input type="text" class="form-control" name="title" id="title" placeholder="video title" value="<%= old('title') %>">
</div>
</div>
<div class="form-group row">
<div class="col">
<label for="artist" class="control-label font-weight-bold font-weight-bold">linked Artist</label>
<select name="artist" id="artist" class="form-control">
<% artists.forEach(artist => { %>
<option value="<%= artist._id %>" <%= String(old('artist')) == String(artist._id) ? 'selected' : '' %> ><%= artist.name %></option>
<% }) %>
</select>
</div>
<div class="col">
<label for="time" class="control-label font-weight-bold">Video Length</label>
<input type="text" class="form-control" name="time" id="time" placeholder="enter video length" value="<%= old('time') %>">
</div>
</div>
<div class="form-group row">
<div class="col">
<label for="videos" class="control-label font-weight-bold">Video File</label>
<input type="file" class="form-control" name="videos" id="videos" placeholder="Enter video file" >
</div>
</div>
<div class="form-group row">
<div class="col">
<button type="submit" class="btn btn-danger">Create</button>
</div>
</div>
</form>
这是我的上传文件夹的屏幕截图,其中正确保存了视频并且可以播放
enter image description here
我刚刚意识到我忘记添加 convertFileToField 中间件。
现在工作正常
handle(req , res , next) {
if(! req.file)
req.body.videos = undefined;
else
req.body.videos = req.file.filename;
next();
}
我正在尝试使用 multer 上传视频,我有一个表单和所有内容,但是当我单击创建时,验证器给出了一个错误,但是文件保存在我的目录中,就好像验证成功一样。 我正在为数据库使用 mongoDB。
这是验证器
const { check } = require('express-validator/check');
const Video = require('app/models/VideoModel');
const path = require('path');
class videoValidator extends validator {
handle() {
return [
check('title')
.isLength({ min : 5 })
.withMessage('title should be at least 5 characters'),
check('artist')
.not().isEmpty()
.withMessage('artist field can not be empty'),
check('videos')
.custom(async (value , { req }) => {
if(req.query._method === 'put' && value === undefined) return;
if(! value)
throw new Error('the video field can not remain empty');
let fileExt = ['.webm' , '.ogg' , '.mp4' , '.avi'];
if(! fileExt.includes(path.extname(value)))
throw new Error('file extention is not supported')
}),
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g , "-")
}
}
module.exports = new videoValidator();
视频控制器
async create(req , res) {
let artists = await Artist.find({});
res.render('admin/videos/create' , { artists });
}
async store(req , res , next) {
try {
let status = await this.validationData(req);
if(! status) return this.back(req,res);
let videos = req.file;
let { title , artist } = req.body;
let newVideo = new Video({
artist,
title,
slug : this.slug(title),
videos,
});
await newVideo.save();
return res.redirect('/admin/videos');
} catch(err) {
next(err);
}
}
路由和上传助手
const videoUpload = require('app/helpers/uploadVideo');
// video Routes
router.get('/videos' , videoController.index);
router.get('/videos/create' , videoController.create);
router.post('/videos/create' ,
videoUpload.single('videos'),
videoValidator.handle(),
videoController.store
);
const multer = require('multer');
const path = require('path');
const mkdirp = require('mkdirp');
const fs = require('fs');
const getDirVideo = () => {
let year = new Date().getFullYear();
let month = new Date().getMonth() + 1;
let day = new Date().getDay();
return `./public/uploads/videos/${year}/${month}/${day}`;
}
const videoStorage = multer.diskStorage({
destination : (req , file , cb) => {
let dir = getDirVideo();
mkdirp(dir , (err) => cb(null , dir))
},
filename : (req , file , cb) => {
let filePath = getDirVideo() + '/' + file.originalname;
if(!fs.existsSync(filePath))
cb(null , file.originalname);
else
cb(null , Date.now() + '-' + file.originalname);
}
})
const uploadVideo = multer({
storage : videoStorage,
limits : {
fileSize : 1024 * 1024 * 40
}
});
module.exports = uploadVideo;
型号和ejs
const videoSchema = Schema({
artist: {
type : Schema.Types.ObjectId,
ref : 'Artist'
},
title: {
type : String,
required : true
},
videos: {
type : Object,
required : true
},
time: {
type: String,
default : '00:00:00'
},
videoUrl: {
type : String,
required : true
},
} , { timestamps : true });
module.exports = mongoose.model('Video' , videoSchema);
<div class="d-flex justify-content-between align-items-center mb-3 pb-2 border-bottom">
<h2>add Video</h2>
</div>
<form class="form-horizontal" action="/admin/videos/create" method="post" enctype="multipart/form-data">
<%- include(viewPath('layouts/error-messages')) -%>
<div class="form-group row">
<div class="col">
<label for="title" class="control-label font-weight-bold">Video Title </label>
<input type="text" class="form-control" name="title" id="title" placeholder="video title" value="<%= old('title') %>">
</div>
</div>
<div class="form-group row">
<div class="col">
<label for="artist" class="control-label font-weight-bold font-weight-bold">linked Artist</label>
<select name="artist" id="artist" class="form-control">
<% artists.forEach(artist => { %>
<option value="<%= artist._id %>" <%= String(old('artist')) == String(artist._id) ? 'selected' : '' %> ><%= artist.name %></option>
<% }) %>
</select>
</div>
<div class="col">
<label for="time" class="control-label font-weight-bold">Video Length</label>
<input type="text" class="form-control" name="time" id="time" placeholder="enter video length" value="<%= old('time') %>">
</div>
</div>
<div class="form-group row">
<div class="col">
<label for="videos" class="control-label font-weight-bold">Video File</label>
<input type="file" class="form-control" name="videos" id="videos" placeholder="Enter video file" >
</div>
</div>
<div class="form-group row">
<div class="col">
<button type="submit" class="btn btn-danger">Create</button>
</div>
</div>
</form>
这是我的上传文件夹的屏幕截图,其中正确保存了视频并且可以播放
enter image description here
我刚刚意识到我忘记添加 convertFileToField 中间件。 现在工作正常
handle(req , res , next) {
if(! req.file)
req.body.videos = undefined;
else
req.body.videos = req.file.filename;
next();
}