wrkbrs

[node.js] body-parser을 정확히 알자 본문

Node.js

[node.js] body-parser을 정확히 알자

zcarc 2019. 12. 20. 06:33

express를 사용하면 보통 아래와 같이 시작을 한다.

const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true}); ...

보통 body-parser를 설명할때 'request.body에 있는 데이터에 접근하기 위해 사용한다' 라고 간략히 설명을 한다.
그럼 아래와 같은 질문을 할수있다.

1. 그럼 bodyParser.json()은 정확히 뭘 하는거고,
2. bodyParser.urlencoded()는 뭘하는거고,
3. extended: false일때와 extended: true일 때는 뭐가 다른건데?

여러 블로그를 찾아봤지만 제대로 설명해주는 곳이 없었다. 그러다 아래의 블로그를 발견했다. (중국어 블로그)

bodyParser中间件的研究 - 那些年遇到过的坑 - SegmentFault 思否

bodyParser中间件的研究 接触nodejs已有一段时间了,但最近才开始落实项目,于是使用express应用生成器生成了一个应用。开发过程中发现ajax提交的数据无法被express正确的解析,主要的情况是这样的: // 浏览器端post一个对象 $.ajax({ url : "/save" , type : "post" , data : { name : "henry" , age : 30 , hobby : [ "sport" , "coding" ] } }); // e

segmentfault.com

 

◇ bodyParser.json()과 bodyParser.urlencoded()는 무엇을 하는가?


1. bodyParser.json()은 'application/json' 방식의 Content-Type 데이터를 받아준다.
2. bodyParser.text()는 'text/xml' 방식의 Content-Type 데이터를 받아준다.
3. bodyParser.urlencoded({...})는 'application/x-www-form-urlencoded' 방식의 Content-Type 데이터를 받아준다. (jQuery.ajax의 기본 타입)
4. etc.


◇ extended: true와 extended: false는 무엇이 다른가?

The extended option allows to choose between parsing the URL-encoded data with the querystring library (when false) or the qs library (when true). Defaults to true, but using the default has been deprecated

번역하자면 "extended 옵션을 false로 하면 내부적으로 querystring library를 사용, true로 하면 내부적으로 qs library를 사용하여 URL-encoded data를 파싱한다. 기본적으로 true지만, deprecated 되었다" 정도 되겠다.

즉, false와 true는 data를 인코딩하는 방식을 선택하는 옵션이라 보면 되겠다. 그렇다면 querystring과 qs의 동작을 이해해야 뭐가 다른지 알수있겠지.

querystring.parse("name=henry&age=30") => { name: 'henry', age: '30' }

qs.parse("name=henry&age=30") => { name: 'henry', age: '30' }

뭐 어쩌라고? 똑같잖아..

기본적으로 같은 동작방식을 가진다. 하지만, 전달되는 객체(object)에 depth가 있을경우에 인코딩 방식이 달라진다.

let data = { info: { name: 'henry', age: 30 }, hobby[1]: sport, hobby[2]: coding };

querystring.parse(data)의 결과 : { 'info[name]': 'henry', 'info[age]': '30', 'hobby[1]': 'sport', 'hobby[2]': 'coding' }

qs.parse(data) 의 결과 : { info: { name: 'henry', age: '30' }, hobby: ['sport', 'coding'] }

즉, 데이터에 depth가 있을 경우 querystring은 키값에 depth를 모두 포함한다. 그리고 qs는 depth를 잘 나눠준다.

但是qs也不是万能的,对于多级嵌套的对象,qs只会解析5层嵌套,超出的部分会表现的跟本文头部的那种情况一样;对于数组,qs最大只会解析20个索引,超出的部分将会以键值对的形式解析。

위 블로그에 따르면 qs도 최대 5뎁스까지만 인코딩 가능하다고 한다. 그 이상은 querystring과 같다고. 또한 qs가 인코딩 가능한 최대 색인(데이터의 내부 키..?)는 20개까지라고 한다.

◇ data의 타입

let data = { info: { name: 'henry', age: 30 }, hobby[1]: sport, hobby[2]: coding };

위 데이터를 보면 age를 int형식으로 담고 있다. 하지만, jQuery.ajax를 통해 요청을 하게되면 아래와 같이 인코딩 되어 받게된다. 즉, string 혹은 object로 받게되는 것이다.

{ info: { name: 'henry', age: '30' }, hobby: ['sport', 'coding'] }

만약 int 타입으로 받고 싶다면 (원래 타입) 어떻게 해야할까?
jQuery.ajax의 contentType은 기본적으로 'application/x-www-form-urlencoded' 방식을 사용한다.
contentType을 'application/json'으로 하여 bodyParser.json() 을 통해 받으면 원래의 타입 그대로 받을수 있다.

 

[출처] [node.js] body-parser을 정확히 알자|작성자 Dreamy