本项目为系列博客,目前有以下系列
- Node.js+Express+MongoDB 建站实例(1)-- 网站初始化
- Node.js+Express+MongoDB 建站实例(2)-- 登录模块
- [Node.js+Express+MongoDB 建站实例(3)-- 上传图片及其他模块]
- Node.js+Express+MongoDB 建站实例(4)-- react构建前端页面对接接口:项目源码
本文源码请看 https://github.com/jiaoyanlin/myNodeProject/tree/c5237306394c4896aee804a3d378dd2a92be24e0
其他模块
由于上两篇文章中已经将如何往数据库中插入、修改数据等做了演示,因此这篇文章就不再重复了,主要记录一些开发时遇到的问题及解决方案(具体实现方法看源码)。
1、 这边推荐使用postman进行接口测试,postman网上有很多教程可以看,主要提一下,在使用postman提交post请求时,注意body中选择x-www-form-urlencoded模式来发送,否则后台这边无法通过req.body.xxx来获取参数。
2、 使用mongodb查询数据库时我们有时会使用_id作为参数进行查询,但是直接将它作为条件是查询不到的,应该按照下方这样来查询:
var ObjectId = require('mongodb').ObjectId;
...
// 更新个人信息
exports.updateUserinfo = function (req, res, next) {
let newData = {
"name": req.body.name,
"phone": req.body.phone,
"motto": req.body.motto
};
if (!testTel(req.body.phone)) {
return res.json({
"code": 401,
"message": "手机号码格式不正确"
})
}
// 注意这里用ObjectId(req.cookies.id)
db.updateMany('users', { "_id": ObjectId(req.cookies.id) }, newData, function (err, result) {
if (err) {
return res.json({
"code": 401,
"message": "更新失败"
})
}
return res.json({
"code": 200,
"message": "更新成功"
})
})
}
图片上传模块
1、安装依赖
npm install formidable silly-datetime --save
2、前端使用ajax的formdata进行上传图片(为了测试也可直接用postman上传,注意body中选择form-data)
<div>图片上传:<input type="file" name="fileToUpload" id="fileToUpload" class="fileupload" /></div>
<img style="width: 100px;" />
// 图片上传
$('.fileupload').change(function(event) {
if ($('.fileupload').val().length) {
var fileName = $('.fileupload').val();
var extension = fileName.substring(fileName.lastIndexOf('.'), fileName.length).toLowerCase();
if (extension == ".jpg" || extension == ".png") {
var data = new FormData();
data.append('fulAvatar', $('#fileToUpload')[0].files[0]);
$.ajax({
url: '/api/uploadImg',
type: 'POST',
data: data,
cache: false,
contentType: false, //不可缺参数
processData: false, //不可缺参数
success: function(data) {
console.log('-------upload img:', data);
},
error: function() {
console.log('error');
}
});
}
}
});
注意:由于我们再app.js中用了静态服务app.use(express.static(path.join(__dirname, ‘public’)));
,
将所有的静态资源文件都托管到public文件夹里。后续操作中如果需要调用public中的图片什么的,
无论你在哪个文件夹,都把自己当成是在public文件夹即可。
例如这边可以使用类似![](/avatar/0.2991991519596453.jpg)
来引用public下avatar中的图片
3、后台项目中使用:
// routes/index.js中
// 上传图片
router.route('/api/uploadImg').all(verifyToken).post(api.uploadImg);
// routes/api.js中
const formidable = require('formidable');
var sd = require("silly-datetime");
const fs = require('fs');
var AVATAR_UPLOAD_FOLDER = '/avatar/'; // 上传图片存放路径,注意在本项目public文件夹下面新建avatar文件夹
// 上传图片
exports.uploadImg = function (req, res, next) {
var form = new formidable.IncomingForm(); //创建上传表单
form.encoding = 'utf-8'; //设置编辑
form.uploadDir = 'public' + AVATAR_UPLOAD_FOLDER; //设置上传目录
form.keepExtensions = true; //保留后缀
form.maxFieldsSize = 2 * 1024 * 1024; //文件大小
form.parse(req, function (err, fields, files) {
if (err) {
return res.json({
"code": 500,
"message": "内部服务器错误"
})
}
// 限制文件大小 单位默认字节 这里限制大小为2m
if (files.fulAvatar.size > form.maxFieldsSize) {
fs.unlink(files.fulAvatar.path)
return res.json({
"code": 401,
"message": "图片应小于2M"
})
}
var extName = ''; //后缀名
switch (files.fulAvatar.type) {
case 'image/pjpeg':
extName = 'jpg';
break;
case 'image/jpeg':
extName = 'jpg';
break;
case 'image/png':
extName = 'png';
break;
case 'image/x-png':
extName = 'png';
break;
}
if (extName.length == 0) {
return res.json({
"code": 404,
"message": "只支持png和jpg格式图片"
})
}
//使用第三方模块silly-datetime
var t = sd.format(new Date(), 'YYYYMMDDHHmmss');
//生成随机数
var ran = parseInt(Math.random() * 8999 + 10000);
// 生成新图片名称
var avatarName = t + '_' + ran + '.' + extName;
// 新图片路径
var newPath = form.uploadDir + avatarName;
// 更改名字和路径
fs.rename(files.fulAvatar.path, newPath, function (err) {
if (err) {
return res.json({
"code": 401,
"message": "图片上传失败"
})
}
return res.json({
"code": 200,
"message": "上传成功",
result: AVATAR_UPLOAD_FOLDER + avatarName
})
})
});
}
上传文件测试后,可以到上传文件夹public/avatar下查看是否成功
源码: GitHub
下一篇文章打算使用react简单构建前端页面,使用这边开发的接口进行开发。