1. 程式人生 > >Node.js+Express+MongoDB 建站例項——上傳圖片及其他模組

Node.js+Express+MongoDB 建站例項——上傳圖片及其他模組

本專案為系列部落格,目前有以下系列

其他模組

由於上兩篇文章中已經將如何往資料庫中插入、修改資料等做了演示,因此這篇文章就不再重複了,主要記錄一些開發時遇到的問題及解決方案(具體實現方法看原始碼)。

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簡單構建前端頁面,使用這邊開發的介面進行開發。