解决影院项目的图片上传问题
在上一篇博文中也说了,我们这个影院项目中有一个电影管理模块,这个模块中就牵扯到电影的海报上传的问题,下面我就分别针对前端和后台说下相应的处理:
前端部分
主要是借助FormData完成的,前端采用的是Vue,所以是下面的写法
submit : function() {
var formData = new FormData();
formData.append("path", document.getElementById("file").files[0]);
formData.append('movieName', this.movie.movieName);
formData.append('movieType', $('.edit').find('select').eq(0).val());
formData.append('movieSummary', this.movie.movieSummary);
formData.append('movieDirector', this.movie.movieDirector);
formData.append('movieActor', this.movie.movieActor);
formData.append('movieLong', this.movie.movieLong);
formData.append('movieLanguage', this.movie.movieLanguage);
formData.append('price', this.movie.price);
this.$http.post('/api/movie/add', formData)
.then((response) => {
if(response.data.error) {
$('#err').val("添加失败,请重试");
}else {
this.$router.push('/movie');
}
});
}
当时我在控制台输出这个FormData对象的实例的时候,一看到它出现是空的时候,我就有点紧张,以为没有取到值,如下面所示:
所以就重新定义了一个对象,并且输出:
var movie = {
movieName : this.movie.movieName,
movieType : $('.edit').find('select').eq(0).val(),
movieSummary : this.movie.movieSummary,
movieDirector: this.movie.movieDirector,
movieActor: this.movie.movieActor,
movieLong : this.movie.movieLong,
movieLanguage : this.movie.movieLanguage,
price : this.movie.price,
};
console.log(movie);
输出结果,我看到之后,才知道没有错误,这才“放心大胆”的去专心处理后台的处理的
后台部分
我承认的一点就是我的Node.js没有达到那种熟练掌握各种模块的使用的地步,之前也没有用过Node写过文件上传的东西(之前用Java做后台的时候,倒是接触过这部分),所以我在后台的处理函数里面第一次尝试的是通过body-parser模块来处理前端发来的post请求,但是当我利用 req.body.** 输出的内容都是空的,那个时候的第一个反应还是担心数据没有传过来,然后又去查询了一下别人的博客和别人对于文件处理的方式,我就找到了formidable 这个东西,之前也没有用过,然后参考别人提供的例子,写出来关于添加电影的后台:
router.post('/api/movie/add', (req, res) => {
var obj ={};
var form = new formidable.IncomingForm({
encoding:"utf-8",
uploadDir:"../dist/resource", //文件上传地址
keepExtensions:true //保留后缀
});
form.parse(req)
.on('field', function(name, value) { // 对于字段
obj[name] = value;
})
.on('file', function(name, file) { //对于文件
obj[name] = file;
})
.on('error', function(error) {
})
.on('end', function() { //结束时候
obj.path = obj.path.path.substring(1).split('\\').join('/').split('./dist/')[1];
obj.state = 0;
new models.Movies(obj).save((err, data) => {
if(err) {
res.send({error : 'error'});
} else {
res.send('addMovie successed');
}
});
});
});
在写uploadDir这个路径的时候,改了好几次,原因就是刚开始时在写路径的时候,是放在static目录下的,然后之后在展示电影信息的时候没有加载出海报,原因就是webpack将存放在static目录下的东西都会打包到dist目录底下,而我写的vue页面也会打包到dist目录下的static目录下的,所以之后进行了调整,然后放在/dist/resource目录下,然后查看信息的时候显示正常。
扩展学习
关于formidable的安装
npm install formidable –save -d
npm 上对于formidable的介绍:https://www.npmjs.com/package/formidable
multiparty 也可以实现表单的解析功能
function multiparty (req,callback) {
var form = new multiparty.Form({
encoding:"utf-8",
uploadDir:"../dist/resource", //文件上传地址
keepExtensions:true //保留后缀
})
form.parse(req, function(err, fields, files) {
var obj ={};
Object.keys(fields).forEach(function(name) {
obj[name] = fields[name];
});
Object.keys(files).forEach(function(name) {
obj[name] = files[name];
});
callback(err,obj);
});
}
这个和formidable都是可以实现解析表单的功能的,但是它们返回值的数据结构和字段名称不同,另一方面关于它们的解析结果的呈现也不一样,multiparty 返回值是数组格式的