Node.js+Express+MongoDB 建站例項——上傳圖片及其他模組
阿新 • • 發佈:2019-01-27
本專案為系列部落格,目前有以下系列
其他模組
由於上兩篇文章中已經將如何往資料庫中插入、修改資料等做了演示,因此這篇文章就不再重複了,主要記錄一些開發時遇到的問題及解決方案(具體實現方法看原始碼)。
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資料夾即可。
例如這邊可以使用類似<img style="width: 100px;" src="/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下檢視是否成功
下一篇文章打算使用react簡單構建前端頁面,使用這邊開發的介面進行開發。