zoukankan      html  css  js  c++  java
  • NODEJS文件上传

    基于NodeJs的文件上传

    0.7612018.04.02 22:38:00字数 785阅读 19,969

    最近,自己玩nodeJs,用上了Express框架,小白。上传文件,查了写资料。
    发现了有req.files这个接口,然后试了下。

    使用req.files

    Express默认的上传路径为/tmp。如果是windows系统,会有报错。所以,你可以指定上传的临时目录:

    //默认临时目录
    //app.use(express.bodyParser());
    //修改自定义目录,V2.5.4版本之后支持
    app.use(express.bodyParser({uploadDir:'./uploads'}));
    

    使用方法:
    前端:

    <form action="/uploadImg" method="post" enctype="multipart/form-data">
        <h2>单图上传</h2>
        <input type="file" name="logo">
        <input type="submit" value="提交">
    </form>
    

    nodeJs

    app.post('/uploadImg', function(req, res, next) {
      console.log(req.body);
      console.log(req.files);
      //获取详细信息
      var file = req.files.logo;//From the name
      console.log('文件类型:%s', file.type);
      console.log('原始文件名:%s', file.name);
      console.log('文件大小:%s', file.size);
      console.log('文件保存路径:%s', file.path);
    });
    

    其中,通过定义的对象名来获取具体的file对象。常用属性:

    • size ---- 文件大小(bytes)
    • path ---- 文件上传后的路径
    • name ---- 文件的原始文件名称.
    • type ----文件类型

    同时,通过express上传的目录都是临时目录,如果要进行永久性保存,还需要将其移动到项目的文件存放目录下。
    这里有一个实例

    // 移动文件需要使用fs模块
       var fs = require('fs');
       app.post('/file-upload', function(req, res) {
         // 获得文件的临时路径
         var tmp_path = req.files.thumbnail.path;
        // 指定文件上传后的目录 - 示例为"images"目录。 
        var target_path = './public/images/' + req.files.thumbnail.name;
        // 移动文件
        fs.rename(tmp_path, target_path, function(err) {
          if (err) throw err;
          // 删除临时文件夹文件, 
          fs.unlink(tmp_path, function() {
             if (err) throw err;
             res.send('File uploaded to: ' + target_path + ' - ' + req.files.thumbnail.size + ' bytes');
          });
        });
      };
    

    但是发现,express项目运行出错:

    Error: Most middleware (like bodyParser) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
    

    查了一下官方文档,才发现:

    In Express 4, req.files is no longer available on the req object by default. To access uploaded files on the req.files object, use a multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty, or pez.

    解决问题,使用中间件。

    支持文件上传中间件

    因为时间有限,并没有做很深入的了解,看了下busboy的使用方法,感觉略麻烦。然后去multer看了下,发现其是在busboy上进行了封装,使其更加高效。决定使用它进行更新。

    安装multer

    npm install express multer multer --save
    下面实例均来自Nodejs进阶:基于express+multer的文件上传

    单图上传

    nodeJs

    var fs = require('fs');
    var express = require('express');
    var multer  = require('multer')
    
    var app = express();
    var upload = multer({ dest: 'upload/' });
    
    // 单图上传
    app.post('/upload', upload.single('logo'), function(req, res, next){
        res.send({ret_code: '0'});
    });
    
    app.get('/form', function(req, res, next){
        var form = fs.readFileSync('./form.html', {encoding: 'utf8'});
        res.send(form);
    });
    
    app.listen(3000);
    

    html:

    <form action="/upload-single" method="post" enctype="multipart/form-data">
        <h2>单图上传</h2>
        <input type="file" name="logo">
        <input type="submit" value="提交">
    </form>
    

    点击提交之后,图片会直接下载到服务器的指定目录下,也就是upload/目录。

    多图上传

    nodeJs

    var fs = require('fs');
    var express = require('express');
    var multer  = require('multer')
    
    var app = express();
    var upload = multer({ dest: 'upload/' });
    
    // 多图上传
    app.post('/upload', upload.array('logo', 2), function(req, res, next){
        res.send({ret_code: '0'});
    });
    
    app.get('/form', function(req, res, next){
        var form = fs.readFileSync('./form.html', {encoding: 'utf8'});
        res.send(form);
    });
    
    app.listen(3000);
    

    html:

    <form action="/upload-multi" method="post" enctype="multipart/form-data">
        <h2>多图上传</h2>
        <input type="file" name="logo">
        <input type="file" name="logo">
        <input type="submit" value="提交">
    </form>
    
    获得图片信息

    通过multer,我们可以获取:

    • 原始文件名
    • 文件大小
    • 本地保存路径
    • 文件类型
      与老的方法相似,multer将文件信息一并保存到了file对象中。

    nodeJs

    var fs = require('fs');
    var express = require('express');
    var multer  = require('multer')
    
    var app = express();
    var upload = multer({ dest: 'upload/' });
    
    // 单图上传
    app.post('/upload', upload.single('logo'), function(req, res, next){
        var file = req.file;
    
        console.log('文件类型:%s', file.mimetype);
        console.log('原始文件名:%s', file.originalname);
        console.log('文件大小:%s', file.size);
        console.log('文件保存路径:%s', file.path);
    
        res.send({ret_code: '0'});
    });
    
    app.get('/form', function(req, res, next){
        var form = fs.readFileSync('./form.html', {encoding: 'utf8'});
        res.send(form);
    });
    
    app.listen(3000);
    

    html:

    <form action="/upload" method="post" enctype="multipart/form-data">
        <h2>单图上传</h2>
        <input type="file" name="logo">
        <input type="submit" value="提交">
    </form>
    

    简单尝试之后,发现上传的文件有两个特性:

    • 文件名是一个hash字符串。而且上传同一个文件名称不一样。(之后再看源码,理解一下
    • 文件是无格式的,也就是说没有后缀名

    笔者给其加入后缀名后即可浏览。所以现在需要做的就是自定义文件名。

    自定义上传路径和文件名

    自定义本地保存的路径,修改dest配置项。
    var upload = multer({ dest: 'upload/' });

    自定义文件名,需要使用mukter的Storage参数,来对资源的保存路径和文件名进行个性化设置。

    • destination:设置资源的保存路径。注意,如果没有这个配置项,默认会保存在 /tmp/uploads 下。此外,路径需要自己创建。
    • filename:设置资源保存在本地的文件名。

    nodeJs

    var fs = require('fs');
    var express = require('express');
    var multer  = require('multer')
    
    var app = express();
    
    var createFolder = function(folder){
        try{
            fs.accessSync(folder); 
        }catch(e){
            fs.mkdirSync(folder);
        }  
    };
    
    var uploadFolder = './upload/';
    
    createFolder(uploadFolder);
    
    // 通过 filename 属性定制
    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, uploadFolder);    // 保存的路径,备注:需要自己创建
        },
        filename: function (req, file, cb) {
            // 将保存文件名设置为 字段名 + 时间戳,比如 logo-1478521468943
            cb(null, file.fieldname + '-' + Date.now());  
        }
    });
    
    // 通过 storage 选项来对 上传行为 进行定制化
    var upload = multer({ storage: storage })
    
    // 单图上传
    app.post('/upload', upload.single('logo'), function(req, res, next){
        var file = req.file;
        res.send({ret_code: '0'});
    });
    
    app.get('/form', function(req, res, next){
        var form = fs.readFileSync('./form.html', {encoding: 'utf8'});
        res.send(form);
    });
    
    app.listen(3000);
    

    html:

    <form action="/upload" method="post" enctype="multipart/form-data">
        <h2>单图上传</h2>
        <input type="file" name="logo">
        <input type="submit" value="提交">
    </form>
    
  • 相关阅读:
    python 代码规范
    Helm 入门指南
    思路和决断
    awk替换第几行第几列的值
    一个awk命令的demo
    装饰模式
    Java多线程Thread.yield(),thread.join(), Thread.sleep(200),Object.wait(),Object.notify(),Object.notifyAll()的区别
    类继承时,构造函数和析构函数的调用次序
    C++中delete和 delete[]的区别
    回溯
  • 原文地址:https://www.cnblogs.com/justart/p/12746527.html
Copyright © 2011-2022 走看看