NodeJs之文件上傳


NodeJs之文件上傳

一,介紹與需求

1.1,介紹

1,multer模塊

multer用於處理文件上傳的nodejs中間件,主要跟express框架搭配使用,只支持表單MIME編碼為multipart/form-data類型的數據請求.

2,fs模塊

fs模塊用於對系統文件及目錄進行讀寫操作。

1.2,需求

上傳並操作文件與文件目錄

二,配置實現

2.1,multer模塊

第一步:安裝multer模塊

1 cnpm install multer --save

第二步:引入multer模塊,構造multer對象: multer(opt)

 opt是個key-value對象,包含屬性dest/storage,fileFilter,limits.分表表示文件的存儲位置/方式,文件過濾,文件大小限制.如下:

 1 var moment = require("moment");
 2 var express = require("express");
 3 var multer = require('multer');
 4 var storage = multer.diskStorage({
 5   //文件存儲路徑
 6     destination: function (req, file, cb) {
 7         cb(null, path.join(__dirname, "/../uploads/temps"));
 8     },
 9    //修改上傳文件的名字
10    //file 是個文件對象 ,fieldname對應在客戶端的name屬性
11    //存儲的文件需要自己加上文件的后綴,multer並不會自動添加
12    //這里直接忽略文件的后綴.
13     filename: function (req, file, cb) {
14         var date = new Date();
15         cb(null, moment().format("YYYYMMDDhhmmss") + file.originalname);
16     }
17 });
18 let objMulter = multer({storage : storage });

如果初始化multer時候沒有指定dest或者storage,上傳的文件將保存在內存中,永遠不會寫入到磁盤中,在storage中如果沒有指定destination值,那么上傳的文件將存儲在系統默認的臨時文件夾.

 1 multer關聯的文件信息:
 2 
 3 filedname   : 在form表單中指定的name屬性值
 4 orginalname : 原始文件名
 5 encoding    : 文件編碼方式
 6 mimetype    : 多媒體類型
 7 size        : 文件大小,單位b
 8 destination : 文件上傳后存儲在服務端的路徑
 9 filename    : 文件在服務端的命名
10 path        : 文件在服務端的完整路徑
11 buffer      : 文件二進制數據
12 
13 ps:其中destination,filename和path只有在指定storage屬性時候有效.而buffer只有文件在內存中存儲時候有效.

multer同時提供了single/array/fields/any方法用於對接受文件數的控制.

  1. single(fieldname) 接收單個文件,通過req.file訪問該文件
  2. array(fieldnaem,[maxcount]) 接收多個文件,通過req.files數組方法文件.maxcount指定接收文件最大數.
  3. fields(fields) 接受指定fieldname的文件,fieldname由客戶端決定,通過req.files數組方法
  4. any 接收所有文件上傳,通過req.files訪問文件

2.2,fs模塊

第一步:安裝fs模塊,也可直接引用,node默認集成

1 cnpm install fs --save//項目目錄安裝
2 var fs = require("fs");//直接引入文件系統模塊

第二步:介紹fs模塊的方法

1 var fs = require('fs'); // 載入fs模塊

1,刪除指定文件:fs.unlink(path,callback)

path參數為該文件的絕對物理路徑,callback回調參數當中只有一個錯誤信息參數err,一般在該文件不存在或者刪除文件失敗時觸發調用。

1 fs.unlink('/tmp/234.txt', function(err) {
2     if (err) {
3         throw err;
4     }
5     console.log('成功刪除了 /tmp/234.txt');
6 });

2,讀取文件:fs.readFile(filename,[option],callback)

參數說明:

    • filename String 文件名
    • option Object
      • encoding String |null default=null
      • flag String default='r'
    • callback Function

path參數為該文件的絕對物理路徑,其中options參數可選,可以傳入編碼格式,如讀取文本文件時,可傳入'utf8',若不指定編碼格式,則默認輸出讀取的文件內容為Buffer形式,故一般都會傳入該參數。callback回調參數當中有兩個參數errdata,其中err為錯誤信息參數,一般在在文件不存在或者讀取文件失敗時觸發調用,data為文件內容。

1 fs.readFile('./tmp/test.txt','utf-8'function(err, data) { 
2 // 讀取文件失敗/錯誤
3 if (err) {
4 throw err;
5 }
6 // 讀取文件成功
7 console.log(data);
8 });

3,寫入文件:fs.writeFile(filename,data,[options],callback),追加寫入:fs.appendFile(filename,data[,options],callback)

 filename參數為該文件的絕對物理路徑,data為需要寫入該文件當中的數據內容,其中options參數可選,可以傳入編碼格式,若不傳則默認為utf8callback回調參數當中只有一個錯誤信息參數err,一般在寫入失敗時觸發調用。

 1 // 寫入文件內容(如果文件不存在會創建一個文件)
 2 // 傳遞了追加參數 { 'flag': 'a' }
 3 fs.writeFile('./test2.txt', 'test test', { 'flag': 'a' }, function(err) {
 4     if (err) {
 5         throw err;
 6     }
 7 
 8     console.log('Saved.');
 9 
10     // 寫入成功后讀取測試
11     fs.readFile('./test2.txt', 'utf-8', function(err, data) {
12         if (err) {
13             throw err;
14         }
15         console.log(data);
16     });
17 });

flag傳值,r代表讀取文件,w代表寫文件,a代表追加。

1 // 追加寫入
2 fs.appendFile("2.txt","我是追加的字符",function (err) {
3     if(err){
4       return  console.log(err);
5     }else {
6         console.log("追加成功");
7     }
8 })

4,檢測文件是否存在:fs.exists(path,callback)

path參數傳入該文件的絕對物理路徑,該callback回調函數有個參數exists。exists為一個文件狀態對象,是否存在。

1 var dest_Dir = path.join(__dirname.replace("routes", ""), "uploads", destDir); 
2 fs.exists(dest_Dir, function (exists) {
3         if (exists) {
4          //存在
5         }
6         else {
7           
8         }
9     });

5,移動或重命名指定文件:fs.rename(oldPath,newPath,callback)

oldPath參數為該文件原來的路徑,newPath參數為該文件移動或重命名之后的路徑,這兩個參數都必須能傳入文件完整的絕對物理路徑。callback回調參數當中只有一個錯誤信息參數,一般在oldPath當中指定的文件不存在或者該操作失敗時觸發調用。

1  fs.rename(sourceFile, destPath, function (err) {
2                 res.status(200).json({
3                     httpCode: 200,
4                     message: '上傳成功',
5                     data: {
6                         "fileurl": fileurl
7                     },
8                 });
9 });

6,創建一個目錄文件夾:fs.mkdir(path[,model],callback)

path為該目錄的絕對物理路徑,callback回調函數當中也只有一個錯誤信息參數,一般在目錄創建失敗時觸發調用。

 1  fs.mkdir(dest_Dir, 0777, function (err) {
 2                 if (err) {
 3                     res.status(500).json({
 4                   
 5                 } else {
 6                   //創建目錄成功,上傳文件
 7                     fs.rename(sourceFile, destPath, function (err) {
 8                         res.status(200).json({
 9                             httpCode: 200,
10                             message: '上傳成功',
11                             data: {
12                                 "fileurl": fileurl
13                             },
14                         });
15                     });
16                 }
17 })

7,讀取目錄文件夾:fs.readdir(path,callback)

path為該目錄的絕對物理路徑,callback回調函數當中有兩個參數errfileserr為錯誤信息參數,一般在該目錄不存在或讀取失敗時觸發調用,files為一個數組對象,包含該目錄下的所有文件夾與文件的名字。(僅為文件夾的名字和文件名,不是路徑形式)。

1 fs.readdir('./newdir', function(err, files) {
2     if (err) {
3         throw err;
4     }
5     // files是一個數組
6     // 每個元素是此目錄下的文件或文件夾的名稱
7     console.log(files);
8 });

8,刪除一個空文件夾:fs.rmdir(path,callback)

path為該目錄的絕對物理路徑,callback回調函數當中也只有一個錯誤信息參數,一般在該目錄不存在或者刪除操作失敗時觸發調用。

1 fs.rmdir('/tmp', function(err) {
2     if (err) {
3         throw err;
4     }
5     console.log('成功刪除了 空文件夾 tmp');
6 });

以上的實例均是異步操作,如果需同步操作在函數后面加Sync既可

1 //同步 所有同步的函數都是函數后面加Sync;
2  var res = fs.writeFileSync("1.txt","我是寫入內容");

2.3,文件上傳

1,單文件上傳

 1 router.post('/upload', upload.single('file'), function (req, res, next) {
 2     var fileName = req.file.filename;
 3     var destDir = req.body.dir == undefined ? "default" : req.body.dir;
 4     var sourceFile = req.file.path;
 5     var destPath = path.join(__dirname.replace("routes", ""), "uploads", destDir, fileName);
 6     var dest_Dir = path.join(__dirname.replace("routes", ""), "uploads", destDir);
 7     var fileurl = uploadFileDomin + destPath.substr(destPath.indexOf("uploads"));
 8     fileurl = fileurl.replace(/\\/g, "/");
 9     fs.exists(dest_Dir, function (exists) {
10         if (exists) {
11             fs.rename(sourceFile, destPath, function (err) {
12                 res.status(200).json({
13                     httpCode: 200,
14                     message: '上傳成功',
15                     data: {
16                         "fileurl": fileurl
17                     },
18                 });
19             });
20         }
21         else {
22             fs.mkdir(dest_Dir, 0777, function (err) {
23                 if (err) {
24                     res.status(500).json({
25                         httpCode: 500,
26                         message: err,
27                         data: [],
28                     });
29                 } else {
30                     fs.rename(sourceFile, destPath, function (err) {
31                         res.status(200).json({
32                             httpCode: 200,
33                             message: '上傳成功',
34                             data: {
35                                 "fileurl": fileurl
36                             },
37                         });
38                     });
39                 }
40             })
41         }
42     });
43 
44 });

 2,多文件上傳

 1 router.post('/uploads', upload.array('file', 8), function (req, res, next) {
 2     var paths = [];
 3     for (var i = 0; i < req.files.length; i++) {
 4         var path = req.files[i].path.replace(/\\/g, "/");
 5         var fileurl = uploadFileDomin + path.substr(path.indexOf("uploads")).replace('\\', '/');
 6         paths.push(fileurl);
 7     }
 8     res.status(200).json({
 9         httpCode: 200,
10         message: '上傳成功',
11         "fileurls": paths,
12     });
13 });

 最后拋出發送上傳接口:

1 app.use("/api", require("./fileUploadApi.js"));

三,前端調用

3.1,單文件上傳調用

1,簡單html

1 <span>ajax upload</span>
2     <div class="container">
3         <label>file</label>
4         <input type="file" name="file" id="file">
5         <input type='button' value='上傳' id="btn_upload" />
6     </div>

2,js調用

 1  $("#btn_upload").click(function () {
 2             //創建一個FormDate
 3             var formData = new FormData();
 4             //將文件信息追加到其中
 5             formData.append('file', file.files[0]);
 6             formData.append('dir', 'attachment');
 7             //formData.append('name', file.files[0].name);
 8             $.ajax({
 9             url: "http://localhost:3000/api/" + 'upload',
10             type: 'POST',
11             data: formData,
12             cache: false,
13             contentType: false,
14             processData: false,
15             xhrFields: {
16                 withCredentials: true
17             },
18             crossDomain: true,
19             success: function (data) {
20                 callBack(data);
21             },
22             error: function (response) {
23                 console.log("error is :" + response);
24             }
25         });

3,實現效果

3.2,多文件上傳調用

1,簡單html

1   <span>ajax multi files upload</span>
2     <div class="container">
3         <label>file</label>
4         <input type="file" name="file" id="files1">
5         <input type="file" name="file" id="files2">
6         <input type="file" name="file" id="files3">
7         <input type='button' value='上傳' id="btn_uploads" />
8     </div>

2,js調用

 1         var files1 = $("#files1")[0];
 2         var files2 = $("#files2")[0];
 3         var files3 = $("#files3")[0];
 4         $("#btn_uploads").click(function () {
 5             //創建一個FormDate
 6             var formData = new FormData();
 7             //將文件信息追加到其中
 8             formData.append('file', files1.files[0]);
 9             formData.append('file', files2.files[0]);
10             formData.append('file', files3.files[0]);
11             $.ajax({
12             url: 'http://localhost:3000/api/' + 'uploads',
13             type: 'POST',
14             data: formData,
15             contentType: false,
16             processData: false,
17             async: false,
18             xhrFields: {
19                 withCredentials: true
20             },
21             crossDomain: true,
22             success: function (data) {
23                 callBack(data.fileurls);
24             },
25             error: function (response) {
26                 console.log("error is :" + response);
27             }
28         })
29 })

3,實現效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM