Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
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
Tags
more
Archives
Today
Total
관리 메뉴

melius

[Node.js] FormData 객체 전송 본문

Node.js

[Node.js] FormData 객체 전송

melius102 2020. 1. 29. 11:23

1. Text 데이터 전송

일반적으로 form 태그를 이용하여 Text 데이터를 전송하는 방식은 아래와 같다.

 

1) 클라이언트 코드(with form tag)

<!-- enctype="application/x-www-form-urlencoded" -->
<form id="form1" method="POST" action="/upload1">
    <input type="text" name="text1" value="text01">
    <input type="text" name="text2" value="text02">
    <button id="btn1">submit</button>
</form>

크롬 개발자 도구의 Network 탭에서 Request Headers를 확인하면,

* Content-Type: application/x-www-form-urlencoded

* Form Data: text1=text01&text2=text02

 

Ajax 통신으로 폼 데이터를 전송하기 위한 코드는 아래와 같다.

<script>
    btn1.onclick = function (e) {
        var formData = $("#form1").serialize();
        $.ajax({
            url: "/upload1",
            type: 'POST',
            data: formData,
            success: function (data) {
                alert(data);
            },
            error: function (xhr, status) {
                alert(xhr + " : " + status);
            }
        });
        return false;
    }
</script>

마지막 false 반환값은 버튼의 submit 기능을 차단하기 위한 코드이다.

 

2) 클라이언트 코드(with JSON)

JSON을 이용하여 간단한 Text 데이터를 보낼수 있다.

let data = {
    text1: 'text01',
    text2: 'text02'
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "/upload1", false);
xhr.setRequestHeader("Content-type", "application/json");
xhr.send(JSON.stringify(data));

 

3) 서버 코드

POST 방식으로 전송된 form 데이터를 req 객체의 body 속성에 넣어주기 위해서 Node.js 서버에 아래와 같은 Body Parser 미들웨어를 추가한다.

app.use(express.urlencoded({ extended: false }));
app.use(express.json());

서버에서 받은 req 객체의 body 속성에서 form 데이터의 값을 확인할 수 있다.

app.post('/upload1', (req, res) => {
    console.log(req.headers);
    console.log(req.body.text1, req.body.text2);
    res.send("hello world");
});

 

 

2. Binary 데이터 전송

Text 데이터가 아닌, Image 파일이나 Audio 파일과 같은 Binary 데이터를 서버로 전송하기 위해서는 form 태그의 enctype 속성값을 'multipart/form-data'로 설정한다.

 

1) 클라이언트 코드(with form tag)

<form id="form2" method="POST" action="/upload2" enctype='multipart/form-data'>
    <input type="text" name="text1" value="text01">
    <input type="file" id="files" name="file2" />
    <button id="btn2">submit</button>
</form>

크롬 개발자 도구의 Network 탭에서 Request Headers를 확인하면,

* Content-Type: multipart/form-data; boundary=----xxxxx...

 

Ajax 통신으로 폼 데이터를 전송하기 위한 코드는 아래와 같다. Binary 데이터를 서버로 전송하기 위해서는 FormData 객체를 생성하여 전달한다. Ajax 통신으로 전송시에는 form 태그의 enctype 속성을 생략해도 된다.

<script>
    btn2.onclick = function (e) {
        e.preventDefault();
        var form = $("#form2")[0];
        var formData = new FormData(form);

        $.ajax({
            url: "/upload2",
            // cache: false,
            processData: false,
            contentType: false,
            type: 'POST',
            data: formData,
            success: function (data) {
                alert(data);
            },
            error: function (xhr, status) {
                alert(xhr + " : " + status);
            }
        });
    }
</script>

 

2) 클라이언트 코드(without form tag)

form 태그를 사용하지 않고 FormData 객체를 이용하여 직접 보낼 수도 있다.

<input type="file" id="file3" name="file3" />
<button id="btn3">submit</button>
<script>
    btn3.onclick = function (e) {
        let formdata = new FormData();
        formdata.append("text3", "text03"); // text data
        formdata.append("file3", file3.files[0]); // binary data

        // use XMLHttpRequest
        // let xhr = new XMLHttpRequest();
        // xhr.open("POST", "/upload2", false);
        // // xhr.setRequestHeader("Content-type", "multipart/form-data");
        // xhr.send(formdata);

        // use jQuery
        $.ajax({
            url: '/upload2',
            type: 'POST',
            //async: true,
            //cache: false,
            contentType: false,
            processData: false,
            data: formdata,
            success: function (data) {
                alert(data);
            }
        });
    }
</script>

 

3) 서버 코드

서버로 들어오는 Binary 데이터는 req 객체에서 확인이 가능하다.

app.post('/upload2', (req, res) => {
    var contentType = req.headers['content-type'];
    console.log('contentType: ', contentType);
    var buffer = "";
    req.on('data', function (chunk) {
        buffer += chunk.toString();
    });

    req.on('end', function () {
        console.log('buffer: ', buffer);
        res.end('hello world');
    });
});

buffer 출력에서 확인하게 되면 전달된 데이터의 구조가 복잡하므로 개발자가 직접 분석하기는 쉽지 않으나. multer라는 외부모듈을 사용하면 쉽게 데이터를 받을 수 있다.

$ npm i multer

multer 모듈을 이용한 서버단 코드는 아래와 같다. 우선 파일(Binary 데이터)이 저장될 폴더와 파일명을 지정한다. 아래 코드에서는 폴더의 이름을 'uploads'라고 지정하였고, getFile 함수는 전달된 파일 객체를 받아 서버에 저장될 새로운 이름을 생성하는 함수이다.

let storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, 'uploads');
    },
    filename: function (req, file, cb) {
        cb(null, getFile(file));
    }
});

function getFile(file) {
    let oriFile = file.originalname;
    let ext = path.extname(oriFile);
    let name = path.basename(oriFile, ext);
    let rnd = Math.floor(Math.random() * 90) + 10; // 10 ~ 99
    return Date.now() + '-' + rnd + '-' + name + ext;
}

이렇게 생성된 저장정보를 이용하여 아래와 같이 라우터 부분을 완성한다.

let upload = multer({
    storage: storage
});

// upload.none(): only for text-only multipart form
// upload.single('field-name'): only one file
app.post(['/upload2', '/upload3'], upload.any(), (req, res) => {
    console.log(req.body);
    console.log(req.files);
    res.send("hello world");
});

 

'Node.js' 카테고리의 다른 글

[Node.js] Addons  (0) 2021.03.08
[Node.js] JavaScript Runtime Environment  (0) 2021.02.27
[Node.js] Worker Threads  (0) 2020.02.04
[Node.js] HTTPS 로컬 서버 구축  (0) 2020.01.29
[Node.js] TCP/IP 통신  (0) 2020.01.16
Comments