본문 바로가기
node.js

image upload

by 루에 2015. 12. 11.
반응형

중간과정을 좀 건너 뛰었지만... 기본에 해당하는 부분에서 마지막 파트.


파일 업로드!


기존 코드를 재사용 합니다. 그리고 업로드는 npm에 있는 모듈 중 하나인 formidable을 사용합니다.


formidable의 설치는 터미널에서 npm install formidable



index.js

1
2
3
4
5
6
7
8
9
10
11
12
var server = require("./server");
var router = require("./route");
var requestHandlers = require("./requestHandlers");
 
var handle = {}
handle["/"= requestHandlers.start;
handle["/start"= requestHandlers.start;
handle["/upload"= requestHandlers.upload;
handle["/show"= requestHandlers.show;
 
console.log(handle);
server.start(router.route, handle);
cs


handle에 show가 추가됐습니다. 이미지를 보여주기 위한 메소드입니다.



server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var http = require("http");
var url = require("url");
// var querystring = require("querystring");
 
function start(route, handle){
    function onRequest(request, response){
        var postData = "";
        var pathname = url.parse(request.url).pathname;
        console.log("Request for "+ pathname + "received.");
 
        route(handle, pathname, response, request);
 
        // request.setEncoding("utf8");
 
        // request.addListener("data", function(postDataChunk){
        //     postData += postDataChunk;
        //     console.log("Receuved POST data chunk " + postDataChunk + ".");
        // });
 
        // request.addListener("end", function(){
        //     route(handle, pathname, response, postData);
 
        // });
    }
        // response.writeHead(200, {"Content-Type": "text/plain"});
        // response.write("Hello World");
        // response.end();
 
    http.createServer(onRequest).listen(8888);
    console.log("Server has started");
}
 
exports.start = start;
cs

기존 코드들 중 쓸모 없는 것들은 다 주석처리 했습니다. 

route함수의 파라미터 중 마지막 postData가 request로 변경되었습니다. 그 이유는, 이미지를 업로드 하기 위해 필요하기 때문입니다.


route.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// function route(handle, pathname, response, postData){
function route(handle, pathname, response, request){
    console.log("About to route a request for " + pathname);
    if(typeof handle[pathname] === 'function'){
        // handle[pathname](response,postData);
        handle[pathname](response,request);
    }
    else {
        console.log("No request handler found for" + pathname);
        response.writeHead(404, {"Content-Type""text/plain"});
        response.write("404 Not found");
        response.end();        
    }
}
 
exports.route = route;
cs

별거 없이 주석 처리된 부분만 바뀌었습니다.


requestHandlers.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
var exec = require("child_process").exec;
var querystring = require("querystring");
 
var fs = require("fs");
var formidable = require("formidable");
 
// function start(response,postData) {
function start(response,request) {
    console.log("Request handler 'start' was called");
 
    var body = '<html>'+
    '<head>'+
    '<meta http-equiv="Content-Type" content="text/html; '+
    'charset=UTF-8" />'+
    '</head>'+
    '<body>'+
    '<form action="/upload" enctype="multipart/form-data" method="post">'+
    '<input type="file" name="upload" multiple="multiple">'+
    '<input type="submit" value="Upload File" />'+
    '</form>'+
    '</body>'+
    '</html>';
 
    response.writeHead(200, {"Content-Type""text/html"});
    response.write(body);
    response.end();
 
    // var content = "empty";
// 
    // exec("dir /w", function(error, stdout, stderr){
    //     response.writeHead(200, {"Content-Type": "text/plain"});
    //     response.write(stdout);
    //     response.end();
    // });
// 
    // return content;
}
 
// function upload(response, postData){
function upload(response, request){
    console.log("Request handler 'upload' was called");
    
    var form = new formidable.IncomingForm();
    console.log("parsing done");
    form.parse(request, function(err, fields, files){
    fs.renameSync(files.upload.path, "./tmp/test.png");
    response.writeHead(200, {"Content-Type""text/html"});
    response.write("Received image : <br/>");
    response.write("<img src='/show'/>");
    response.end();        
    });
 
    // response.writeHead(200, {"Content-Type": "text/plain"});
    // response.write("You've sent : " + querystring.parse(postData).text);
    // response.end();
 
 
}
 
function show(response, request){
    console.log("Request handler 'show' was called");
    fs.readFile("./tmp/test.png""binary"function(err, file){
        if(err){
            response.writeHead(500, {"Content-Type""text/plain"});
            response.write(err + "\n");
            response.end();
        }
        else {
            response.writeHead(200, {"Content-Type""image/png"});
            response.write(file, "binary");
            response.end();
        }
    });
}
 
exports.start = start;
exports.upload = upload;
exports.show = show;
cs

먼저 html구문이 파일 업로드를 받기 위해 multipart/form-data형식으로 변경되었고 text fields를 없애고 input type으로 file을 받는 버튼이 생겼습니다.

    '<form action="/upload" enctype="multipart/form-data" method="post">'+
    '<input type="file" name="upload" multiple="multiple">'+
    '<input type="submit" value="Upload File" />'+


그리고 formidable.IncomingForm()을 생성해서 parse()를 이용해 콜백으로 파일을 업로드 합니다. 그 과정에서 fs 모듈이 사용되며(파일을 다루는 모듈) fs.renameSync()를 이용해 파일의 이름을 바꿔줍니다. 이름에서 보는 것처럼 동기적으로 동작하기 때문에 작업 속도가 오래 걸리면 안됩니다. 그리고 이미지를 부릅니다.


show함수에서는 역시 fs모듈을 이용해 readFile() 합니다. 역시 비동기적으로 동작합니다.

반응형

댓글