반응형

nodejs -- Formidable 사용하여 multiple file upload 하기


환경 :  맥 El Capitan, Nodejs 4.2.1, formidable 1.0.17, fs-extra 0.26.7


참고 : https://github.com/felixge/node-formidable     ==> Formidable

         https://www.devbattles.com/en/sand/post-34-Upload+file+in+Node.js+using+formidable

         http://www.codediesel.com/nodejs/processing-file-uploads-in-node-js/

         http://stackoverflow.com/questions/34672568/http-file-upload-in-express-nodejs-server

         https://github.com/jprichardson/node-fs-extra#movesrc-dest-options-callback   ==> fs-extra




<< multiple file 업로드를 위한 HTML 설정 >>


<input type="file" name="upload" multiple="multiple">





<< Formidable >>


** Formidable.IncomingForm


var form = new formidable.IncomingForm();

  --> 새로운 incoming form 생성.


form.encoding = 'utf-8';

  --> Sets encoding for incoming form fields. default = 'utf-8'


form.uploadDir = "/my/dir";

  Sets the directory for placing file uploads in. 

  The default is os.tmpDir().



form.keepExtensions = true;

  form.uploadDir 에 파일 쓸때, 원래 확장자 사용할려면, true 로 해야함.



form.maxFieldsSize = 2 * 1024 * 1024;

  --> 메로리 할당 한계 ; default size is 2MB.



form.hash = false;

  --> checksums ; set this to either 'sha1' or 'md5'.


form.multiples = false;

  --> submit multiple files using the HTML5 multiple attribute

    ; false 로 설정해도, multiple file 업로드에는 지장없으나, true 로 설정해야 form.parse() 에서 util.inspect() 로 볼때  files 객체에 다중 파일보인다..



form.parse(request, [callback]);

   --> Parses an incoming node.js request containing form data.



** Formidable.File


file.size  --> 디스크에 쓰여진 파일 사이즈.


file.path  --> The path this file is being written to.


file.name


file.type  --> The mime type of this file





** Events


'progress'

   --> Emitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar.


form.on('progress', function(bytesReceived, bytesExpected) {

});



'fileBegin'



'error'



'end'

  --> 모든 request를 받고, 디스크에 모든 파일를 쓴후 발생하는 event!

  --> response 보내는 위치.


form.on('end', function() {

});





<< 소스 >>


** <meta charset="utf-8"> 을 생략시에는 한글 파일 업로드시 한글이름깨짐.


var formidable = require('formidable'),
http = require('http'),
util = require('util'),
fs = require('fs-extra');
http.createServer(function(req, res) {
/* Process the form uploads */
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
var form = new formidable.IncomingForm();
console.log(form.multiples);
form.multiples = true;
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
res.end(util.inspect({fields: fields, files: files}));
});
form.on('end', function(fields, files) {
// console.log(this.openedFiles);
console.log(" 총 업로드 파일 갯수 == ", this.openedFiles.length);
for(var i = 0; i < this.openedFiles.length; i++) {
/* Temporary location of our uploaded file */
// 맥에서는 temp_path 가 폴더가 아니라, 업로드한 파일임.
var temp_path = this.openedFiles[i].path;
/* The file name of the uploaded file */
var file_name = this.openedFiles[i].name;
/* Location where we want to copy the uploaded file */
var new_location = './files/';
console.log("temp_path == ", temp_path);
console.log("file_name == ", file_name);
console.log(this.openedFiles[i]);
// temp_path 로 받은 파일을, 원래 이름으로 변경하여 이동시킨다.
fs.move(temp_path, new_location + file_name, function (err) {
if (err) {
console.error(err);
} else {
console.log("success!")
}
});
}
});
return;
}
/* Display the file upload form. */
res.writeHead(200, {'content-type': 'text/html'});
// 한글이름 파일 업로드시 깨지지 않기위해 charset="utf-8" 반드시 포함해야함...
res.end(
'<html>' +
'<head><meta charset="utf-8"></head>' +
'<body>' +
'<form action="/upload" enctype="multipart/form-data" method="post">'+
'<input type="text" name="title"><br>'+
'<input type="file" name="upload" multiple="multiple"><br>'+
'<input type="submit" value="Upload">'+
'</form>'+
'</body></html>'
);
}).listen(3000);




<< progress 이벤트 추가 소스 >>


-- progress 이벤트, error 이벤트 추가함.


form.on('progress', function(bytesReceived, bytesExpected) {

});


form.on('error', function(err) {

});


var formidable = require('formidable'),
http = require('http'),
util = require('util'),
fs = require('fs-extra');
http.createServer(function(req, res) {
/* Process the form uploads */
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
var form = new formidable.IncomingForm();
console.log(form.multiples);
form.multiples = true;
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
console.log("files 갯수 == ", Object.keys(files.upload).length);
console.log("files ==> ", files);
console.log("===============================");
res.end(util.inspect({fields: fields, files: files}));
});
// data 전송중..
form.on('progress', function(bytesReceived, bytesExpected) {
var percent_complete = (bytesReceived / bytesExpected) * 100;
console.log("============ progress ===================");
console.log("bytesReceiveed ==> ", bytesReceived, " ; bytesExpected ==> ", bytesExpected);
console.log(percent_complete.toFixed(2), "% uploaded...");
});
form.on('error', function(err) {
console.log("=========== error ============");
console.error(err);
});
form.on('end', function(fields, files) {
// console.log(this.openedFiles);
console.log(" 총 업로드 파일 갯수 == ", this.openedFiles.length);
// console.log("files ==> ", files);
for(var i = 0; i < this.openedFiles.length; i++) {
/* Temporary location of our uploaded file */
// 맥에서는 temp_path 가 폴더가 아니라, 업로드한 파일임.
var temp_path = this.openedFiles[i].path;
/* The file name of the uploaded file */
var file_name = this.openedFiles[i].name;
/* Location where we want to copy the uploaded file */
var new_location = './files/';
console.log("temp_path == ", temp_path);
console.log("file_name == ", file_name);
console.log(this.openedFiles[i]);
// temp_path 로 받은 파일을, 원래 이름으로 변경하여 이동시킨다.
fs.move(temp_path, new_location + file_name, function (err) {
if (err) {
console.error(err);
} else {
console.log("success!")
}
});
}
});
return;
}
/* Display the file upload form. */
res.writeHead(200, {'content-type': 'text/html'});
// 한글이름 파일 업로드시 깨지지 않기위해 charset="utf-8" 반드시 포함해야함...
res.end(
'<html>' +
'<head><meta charset="utf-8"></head>' +
'<body>' +
'<form action="/upload" enctype="multipart/form-data" method="post">'+
'<input type="text" name="title"><br>'+
'<input type="file" name="upload" multiple="multiple"><br>'+
'<input type="submit" value="Upload">'+
'</form>'+
'</body></html>'
);
}).listen(3000);





반응형
Posted by 자유프로그램
,