node.js實現上傳與下載文件

需求

最近在項目中遇到這樣一個需求:上傳和下載文件。具體情景以下:php

A上傳一份任務文件(文件類型不限)到網站上,B看到後下載文件,按照文件裏的要求完成任務以後,B要把任務完成狀況彙總到一個Excel文檔中,上傳到網站上(此時只能上傳xls格式的excel文檔),而後網站在後臺對這份Excel文檔的數據進行處理,生成一份新的Excel文檔。html

因爲該項目是基於Node.js開發,因此,如何實現文件的上傳下載功能呢?node

實現

思路

  • 編寫form表單頁面express

  • 引入formidable,解析表單數據npm

  • 編寫業務邏輯函數json

編寫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就得不到值了。app

所以,咱們要引入node.js的一個外部模塊:formidable,對錶單數據進行解析。框架

引入formidable,解析表單數據

經過npm引入formidable,npm上formidable的描述爲:dom

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資源,其它的請求路徑都要配置。因此,在上面針對上傳和下載都配置了對應的路由規則。

這樣下來,文件的上傳和下載功能基本實現,具體的擴展和修改看根據項目具體的需求來調整。

相關文章
相關標籤/搜索