【Node.js-5】multer的三种上传情况:单个文件,多个同名文件,多个不同名文件

1、我们之前可以用body-parser或者querystring等模块去获取和处理getpost里面的数据,但是这些数据如果是上传的一个或多个文件呢?这个时候,就需要用multer了。建议直接访问官方文档,因为每个版本的使用不太一样:https://www.npmjs.com/package/multer。

先准备一个html页面,下面的页面是最终的页面,第一次和第二次做实验的时候,其实没有那么多上传的控件,如果有这些控件,但是没有在代码里处理的话,会报错。


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传测试title>
head>
<body>
    <form action="http://localhost:1337/upload" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="username"><br>
        请上传头像1:<input type="file" name="avatar"><br>
        请上传头像2:<input type="file" name="avatar"><br>
        请上传头像3:<input type="file" name="avatar"><br>
        请上传背景:<input type="file" name="bg"><br>
        <input type="submit" value="提交">
    form>
body>
html>

2、我们先看第一种,只上传一个文件的情况,也就是上面的那个html里面我们只用了第一个上传控件,其他的先注释掉:

用户名:type="text" name="username">
请上传头像1type="file" name="avatar">
const express = require('express');
const multer = require('multer');
const expressStatic = require('express-static');

// 这个就是文件上传的存储目录
var upload = multer({dest:'./www/upload'});

var server = express();

server.post('/upload',upload.single('avatar'),function(req,res){
    // 因为是single,所以是一个,需要指定name,下面接收也只用file
    console.log(req.file);
    // 还可以接收一并过来的body数据,multer其实包含了之前的解析post里body的功能
    console.log(req.body);
    res.send('upload success.');
});

server.use(expressStatic('./www'));

server.listen(1337);

我们看看得到的是什么样的结果,所以可以通过originalnamemimetype拿到后缀,可以通过filenamepath得到最终的文件名称和路径:

{ fieldname: 'avatar',
  originalname: '7.png',
  encoding: '7bit',
  mimetype: 'image/png',
  destination: './www/upload',
  filename: 'e70d501dd1263675410c32bd8304be07',
  path: 'www\\upload\\e70d501dd1263675410c32bd8304be07',
  size: 38892 }
{ username: 'eric' }

3、第二种情况就是上传相同的名称的好几个文件,比如上传朋友圈的那种9张图。

用户名:type="text" name="username">
请上传头像1type="file" name="avatar">
请上传头像2type="file" name="avatar">
请上传头像3type="file" name="avatar">
const express = require('express');
const multer = require('multer');
const expressStatic = require('express-static');
const pathLib = require('path');
const fs = require('fs');

var upload = multer({dest:'./www/upload'});

var server = express();

// 这边的数字4不能比html里面的name='avatar'的数量少,否则会报错,这边相当于maxCount,接收几个名字叫做avatar的文件
server.post('/upload',upload.array('avatar',4),function(req,res){
    // 因为是single,所以是一个,需要指定name,下面接收也只用file
    console.log(req.files);
    for (var i = 0; i var newName = req.files[i].path + pathLib.parse(req.files[i].originalname).ext;
        fs.rename(req.files[i].path,newName,function(err){
            if (err) {
                console.log("rename failure.");
            }else{
                console.log("rename success.");
            }
        });
    }
    console.log(req.body);
    res.send('upload success.');
});

server.use(expressStatic('./www'));

server.listen(1337);

结果是一个数组,可以通过for循环,再利用fsrename方法对所有的文件加个后缀:

[ { fieldname: 'avatar',
    originalname: '7.png',
    encoding: '7bit',
    mimetype: 'image/png',
    destination: './www/upload',
    filename: '134594327c1d892bdc7c23f985e443e1',
    path: 'www\\upload\\134594327c1d892bdc7c23f985e443e1',
    size: 38892 },
  { fieldname: 'avatar',
    originalname: '6.png',
    encoding: '7bit',
    mimetype: 'image/png',
    destination: './www/upload',
    filename: '3e8ff491e5b0a4fe2993b63736040bf2',
    path: 'www\\upload\\3e8ff491e5b0a4fe2993b63736040bf2',
    size: 31146 },
  { fieldname: 'avatar',
    originalname: '5.png',
    encoding: '7bit',
    mimetype: 'image/png',
    destination: './www/upload',
    filename: 'e89deeea8a7b44b2f5226f19bfa0eef3',
    path: 'www\\upload\\e89deeea8a7b44b2f5226f19bfa0eef3',
    size: 57466 } ]
{ username: 'aaa' }
rename success.
rename success.
rename success.

4、还有一种比较复杂的情况,就是有很多文件上传吗,而且还不一定是同一个类别(也就是name值可能不同):

用户名:type="text" name="username">
请上传头像1type="file" name="avatar">
请上传头像2type="file" name="avatar">
请上传头像3type="file" name="avatar">
请上传背景:type="file" name="bg">
const express = require('express');
const multer = require('multer');
const expressStatic = require('express-static');
const pathLib = require('path');
const fs = require('fs');

var upload = multer({dest:'./www/upload'});

var server = express();

// 如果出了3个name='avatar'的上传之外,还有一个name='bg'的上传,那么用下面这种方法
server.post('/upload',upload.fields([{name:'avatar',maxCount:3},{name:'bg',maxCount:1}]),function(req,res){
    console.log(req.files);
    for(var i=0;i'avatar'].length;i++){
        var newName = req.files['avatar'][i].path + pathLib.parse(req.files['avatar'][i].originalname).ext;
        fs.rename(req.files['avatar'][i].path,newName,function(err){
            if(err){
                console.log('upload failure.')
            }else{
                console.log('upload success.')
            }
        });
    }
    var newName = req.files['bg'][0].path + pathLib.parse(req.files['bg'][0].originalname).ext;
    fs.rename(req.files['bg'][0].path,newName,function(err){
        if (err) {
            console.log('upload failure.')
        }else{
            console.log('upload success.')
        }
    });
    console.log(req.body);
    res.send('upload success.');
});

server.use(expressStatic('./www'));

server.listen(1337);

我们看一下结果,它其实是个字典,大的字典的key就是每个文件的name,而这个name对应的value是一个数组,不管里面有个文件,都是数组,那么久好办了,要rename的话,那么久一个个的name来处理就行了:

{ avatar: 
   [ { fieldname: 'avatar',
       originalname: '7.png',
       encoding: '7bit',
       mimetype: 'image/png',
       destination: './www/upload',
       filename: '0637965a24bc41fa550008d31f7f03fb',
       path: 'www\\upload\\0637965a24bc41fa550008d31f7f03fb',
       size: 38892 },
     { fieldname: 'avatar',
       originalname: '6.png',
       encoding: '7bit',
       mimetype: 'image/png',
       destination: './www/upload',
       filename: '93c049c585a84fb91fce0d4920b5724d',
       path: 'www\\upload\\93c049c585a84fb91fce0d4920b5724d',
       size: 31146 },
     { fieldname: 'avatar',
       originalname: '5.png',
       encoding: '7bit',
       mimetype: 'image/png',
       destination: './www/upload',
       filename: '237ed62f7016cfb4b4e9495d3beb0199',
       path: 'www\\upload\\237ed62f7016cfb4b4e9495d3beb0199',
       size: 57466 } ],
  bg: 
   [ { fieldname: 'bg',
       originalname: 'jquery1.42.min.js',
       encoding: '7bit',
       mimetype: 'application/javascript',
       destination: './www/upload',
       filename: '9d2613cc8c8d2dd3e23a7e523d3d3ba3',
       path: 'www\\upload\\9d2613cc8c8d2dd3e23a7e523d3d3ba3',
       size: 72326 } ] }
{ username: 'eric' }
upload success.
upload success.
upload success.
upload success.

你可能感兴趣的:(前端)