使用Express JS中的Multer在扩展的基础上过滤文件

时间:2016-07-29 07:24:02

标签: node.js express multer

正如问题标题所解释的,我需要根据文件扩展名过滤上传的文件。所以,我浏览了官方文档并搜索了这个网站。

我尝试过什么

我尝试过遇到的解决方案。文件正在成功上传,但问题是如何过滤文件。目前我的Router.js文件看起来像这样。

Router.JS

var multer  = require('multer');
var storage = multer.diskStorage({ //multers disk storage settings
    destination: function (req, file, cb) {
        cb(null, './public/uploads/')
    },
    limits:{
        files: 1,
        fileSize: 1024 * 1024
    },
    filename: function (req, file, cb) {
        var datetimestamp = Date.now();
        cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
    },
    onFileUploadStart: function(file) {
        console.log("Inside uploads");
        if (file.mimetype == 'image/jpg' || file.mimetype == 'image/jpeg' || file.mimetype == 'image/png') {
            return true;
        }
        else
        {
            return false;
        }
    }
});
var upload = multer({ //multer settings
    storage: storage
}).single('profilepic');


router.post('/profile', function(req, res){
    upload(req,res,function(err){
        if(err)
        {
            console.log(err);
        }
        else
        {
            console.log("Image was uploaded");
        }
    });
});

我尝试回复onFileUploadStart中的某些内容,以检查它是否会进入该功能。事实并非如此。除了onFileUploadStart之外,我还尝试了fileFilter link,但没有帮助。有什么建议如何解决这个问题?提前谢谢。

4 个答案:

答案 0 :(得分:16)

使用multer的示例:

var storage = multer.diskStorage({ //multers disk storage settings
    destination: function (req, file, cb) {
        cb(null, './public/uploads/')
    },
    filename: function (req, file, cb) {
        var datetimestamp = Date.now();
        cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
    }
});

var upload = multer({ //multer settings
    storage: storage,
    fileFilter: function (req, file, callback) {
        var ext = path.extname(file.originalname);
        if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
            return callback(new Error('Only images are allowed'))
        }
        callback(null, true)
    },
    limits:{
        fileSize: 1024 * 1024
    }
}).single('profilepic');

摘自Node.js - File upload。原作者是IcemanMikhail。归因详情可在contributor page上找到。该来源在CC BY-SA 3.0下获得许可,可以在Documentation archive中找到。参考主题ID:4080和示例ID:14210。

答案 1 :(得分:0)

这非常有帮助,谢谢。以我为例,我需要添加一个中间件以确保已安装 JWToken 并使用 XHR 进行构建。如果有人需要帮助,这对我有用。在XHR标头中传递令牌时,可以轻松完成此操作。

客户:

    const loadHandler = event =>{
        // loadHandler mandate
    }

    const errorHandler = event => {
        // error mandate
    }

    const abortHandler = event => {
        // abort mandate
    }

    const data = new FormData()
    data.append('file', upFile)

    var formData = new FormData();
    var xhr = new window.XMLHttpRequest();

    formData.append('files', upFile); // this is a state object set onChange
    xhr.open('post', '/uploadFile', true);
    xhr.setRequestHeader('token', thetoken); // Passing token in header

    xhr.addEventListener("load", loadHandler, false);
    xhr.addEventListener("error", errorHandler, false);
    xhr.addEventListener("abort", abortHandler, false);

    xhr.send(formData);

服务器

const express = require('express'),
      app= express.Router(),
      rf = require('./RoutFuctions');
...
app.post('/uploadFile', rf.verifyToken, function (req, res, next) {
     // upload portion above
});

RoutFunctions.js

const jwt = require('jsonwebtoken')

const tokenTest = (token, res, jwt, caller, next) => {
    jwt.verify(token, process.env.SECRET_KEY, err => {
        if(err) {
          res.sendStatus(403);
          console.log('could not verify token');
        } else {
          console.log("token verified");
          next(); // Next middleware
        }
    });
}

exports.verifyToken = function(req, res, next) {

    if(req.body.token !== undefined) { // non upload scenario
        var caller = ''
        if(req.body.caller !== undefined) caller = req.body.caller;
        tokenTest(req.body.token, res, jwt, caller, next)

    } else {  // attempt to extract token in XHR header upload scenario

      if(req.headers.token !== undefined){
          var token = req.headers.token
          tokenTest(req.headers.token, res, jwt, caller, next)
      } else {
          res.sendStatus(403);
      }
    }
}

答案 2 :(得分:0)

多个或单个文件的完整实现。

注意:对于单个文件使用 .single('filename') 或 .array('filename',1)

  const express = require("express");
  const app = express();
  var session = require('express-session')
  const multer = require("multer");
  const path = require("path");
  var storage = multer.diskStorage({ //multers disk storage settings
    destination: function (req, file, cb) {
        cb(null, path.join(__dirname,"uploads"))
    },
    filename: function (req, file, cb) {
        var datetimestamp = Date.now();
        cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
    }
  });

  var upload = multer({ //multer settings
    storage: storage,
    fileFilter: function (req, file, callback) {
        var ext = path.extname(file.originalname);
        if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
            return callback(new Error('Only images are allowed'))
        }
        callback(null, true)
    },
    limits:{
        fileSize: 1024 * 1024
    }
  }).array('profile',2);
  app.post("/upload", upload,(req, res) => {
    res.json({
      msg:"uploaded"
    })
  });

  app.use((err,req,res,next)=>{
    console.log(err.message);
    res.status(404).json({
      msg:err.message
    })
  })
  app.listen(
    8080,
    (error) => {
      if (error) {
        console.log("error");
      }
    },
    () => {
      console.log("listening at port 8080");
    }
  );

注意:您可以通过扩展 Error 创建自己的自定义错误消息,并在 err、req、res、next 块中发送自定义消息和状态

答案 3 :(得分:-3)

如果您习惯于Web开发,可以在前端验证,而不是传递到后端,您可以尝试:

var file = files[0];  
var imageType = /image.*/;  

if (!file.type.match(imageType)) {  
     // do something  
}