node.js实现上传与下载文件

需求

最近在项目中遇到这样一个需求:上传和下载文件。具体情景如下:

A上传一份任务文件(文件类型不限)到网站上,B看到后下载文件,按照文件里的要求完成任务之后,B要把任务完成情况汇总到一个Excel文档中,上传到网站上(此时只能上传xls格式的excel文档),然后网站在后台对这份Excel文档的数据进行处理,生成一份新的Excel文档。

由于该项目是基于Node.js开发,所以,如何实现文件的上传下载功能呢?

实现

思路

  • 编写form表单页面

  • 引入formidable,解析表单数据

  • 编写业务逻辑函数

编写form表单页面

<!DOCTYPE html>
<html>
<head>
    <title>node.js实现表单上传与下载文件</title>
</head>
<body>
  <form action="/fileupload" method="post" enctype='multipart/form-data'  onsubmit="return checkTask(this)">
    <label for="resource">上传文档</label>
    <input type="file" id="resource" name="resource">
    <button type="submit">新建任务</button>
  </form>

  <a href="download/kkk">下载文件</a>
</body>
</html>

<form>标签中 enctype="multipart/form-data" 作用是设置表单的MIME编码。
默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据。
enctype="multipart/form-data" 是上传二进制数据,form里面的input的值以2进制的方式传过去,所以request就得不到值了。

因此,我们要引入node.js的一个外部模块:formidable,对表单数据进行解析。

引入formidable,解析表单数据

通过npm引入formidable,npm上formidable的描述为:

A node.js module for parsing form data, especially file uploads.

  • 方式一:通过node命令引入:

npm install formidable
  • 方式二:编辑项目工程里的package.json文件:

{
  "name": "appname",
  "virsion": "0.0.1",
  "dependencies": {
    "express": "~4.8.8",
    "formidable": "1.0.14"
  }
}

执行node命令安装模块

npm install

编写业务逻辑函数

1.upload函数

新建一个文件:file.js

var formidable = require('formidable');
var fs = require('fs');  //node.js核心的文件处理模块

exports.upload = function(req, res, next){
  var message = '';
  var form = new formidable.IncomingForm();   //创建上传表单
    form.encoding = 'utf-8';        //设置编辑
    form.uploadDir = 'public/upload/';     //设置上传目录
    form.keepExtensions = true;     //保留后缀
    form.maxFieldsSize = 2 * 1024 * 1024;   //文件大小
  
  form.parse(req, function(err, fields, files) {
    if (err) {
      console.log(err);
    }  

    var filename = files.resource.name;

    // 对文件名进行处理,以应对上传同名文件的情况
      var nameArray = filename.split('.');
      var type = nameArray[nameArray.length-1];
      var name = '';
      for(var i=0; i<nameArray.length-1; i++){
          name = name + nameArray[i];
      }
      var rand = Math.random()*100 + 900;
      var num = parseInt(rand, 10);

      var avatarName = name + num +  '.' + type;

    var newPath = form.uploadDir + avatarName ;
    fs.renameSync(files.resource.path, newPath);  //重命名
  });
};

没有意外的话,文件就上传成功了。

2.download函数

在file.js文件代码末端加入:

exports.download = function(req, res){
  var path = 'public/upload/file.txt';  // 文件存储的路径

  // filename:设置下载时文件的文件名,可不填,则为原名称
  res.download(filepath, filename); 
};

因为该项目应用了Express(一个基于node.js的Web开发框架),其对request,response对象进行了封装,所以可以直接调用封装好了的res对象的download方法,来下载文件。

接下来,在路由控制文件route.js里加入代码:

var file = require("file.js");  //此时,route.js与file.js处于同个目录下

app.post('/fileupload', file.upload);
app.get('/download/:id', file.download);  //结合表单页面的<a>标签,里面的kkk是指该文件的id

因为express进行了路由控制,不是像php,asp原生那样请求路径对应于文件路径。除了static资源,其它的请求路径都要配置。所以,在上面针对上传和下载都配置了对应的路由规则。

这样下来,文件的上传和下载功能基本实现,具体的扩展和修改看根据项目具体的需求来调整。

    原文作者:small2
    原文地址: https://segmentfault.com/a/1190000004057022
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞