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

개발자공부일기

Node.js 2일차 본문

TIL(Today I Learned)

Node.js 2일차

JavaCPP 2024. 11. 19. 20:48

MongoDB를 연결해서 Insomnia로 API들을 테스트 하던 중 req.body의 특정 요소가 undefined라 구조분해할당을 할 수 없다는 오류가 나왔다. 근데 코드는 다 강의를 잘 따라했고 Insomnia에서도 스키마에 맞게 데이터를 잘 집어넣고 있었고

그 오류난 특정 요소도 다 들어있었다. 코드도 req.body도 문제가 없었는데 뭐가 문제였을지 알아봤다.

 

결론부터 말하자면 파싱하는 미들웨어가 필요했다.

 

bodyParser.urlencoded({ extended: true })와 bodyParser.json()을 동시에 사용하면, 클라이언트가 보낸 Content-Type 헤더에 따라 적절한 미들웨어가 요청 본문을 처리합니다. 각각의 처리 과정을 설명드리겠습니다.


1. bodyParser.urlencoded({ extended: true })가 처리하는 데이터

요청 데이터 예시:

  • Content-Type: application/x-www-form-urlencoded
  • 요청 본문:
     
name=John&age=30

처리 과정:

  1. bodyParser.urlencoded()가 작동하여 쿼리 문자열을 파싱합니다.
  2. 결과:
req.body = { name: 'John', age: '30' };

주의사항:

  • 데이터를 key=value 형식으로 보내야 하며, JSON 데이터는 제대로 파싱되지 않습니다.

2. bodyParser.json()이 처리하는 데이터

요청 데이터 예시:

  • Content-Type: application/json
  • 요청 본문:
     
{ "name": "John", "age": 30 }

처리 과정:

  1. bodyParser.json()가 작동하여 JSON 본문을 파싱합니다.
  2. 결과:
     
req.body = { name: 'John', age: 30 };

주의사항:

  • application/json이 아닌 다른 Content-Type으로 요청하면, JSON 본문이 제대로 처리되지 않습니다.

3. 둘 다 선언된 경우 처리 방식

Express는 미들웨어를 순서대로 실행합니다. Content-Type에 따라 적절한 미들웨어가 선택적으로 작동합니다.

요청 처리 흐름:

  1. 요청:
    • 클라이언트는 HTTP 요청의 Content-Type 헤더를 포함시켜 데이터를 보냅니다.
  2. Express 요청 처리:
    • Express는 Content-Type을 보고, 적절한 미들웨어(urlencoded 또는 json)를 실행합니다.
    • 나머지 미들웨어는 무시됩니다.

예시 코드:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

app.use(bodyParser.urlencoded({ extended: true })); // 폼 데이터 처리
app.use(bodyParser.json()); // JSON 데이터 처리

app.post('/data', (req, res) => {
  console.log(req.body); // 요청 데이터를 확인
  res.send('Data received!');
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

동작 결과:

폼 데이터 전송 (Content-Type: application/x-www-form-urlencoded):

요청:

name=Jane&age=25

 

req.body 결과:

{ name: 'Jane', age: '25' }

JSON 데이터 전송 (Content-Type: application/json):

요청:

{ "name": "Jane", "age": 25 }

req.body 결과:

{ name: 'Jane', age: 25 }

4. 잘못된 Content-Type으로 전송하면?

  • 폼 데이터를 JSON으로 전송 (Content-Type: application/json):
    • bodyParser.json()만 동작하려고 하지만, 데이터가 잘못된 형식이므로 파싱 실패.
    • req.body는 undefined 또는 오류를 반환할 수 있습니다.
  • JSON 데이터를 폼 데이터로 전송 (Content-Type: application/x-www-form-urlencoded):
    • bodyParser.urlencoded()가 동작하려고 하지만, JSON 형식을 쿼리 문자열로 해석하려고 해서 파싱 실패.
    • req.body는 비어 있을 가능성이 높습니다.

정리

  • 각각의 미들웨어는 요청의 Content-Type에 따라 작동합니다.
  • urlencoded는 폼 데이터를, json은 JSON 데이터를 처리합니다.
  • 둘을 함께 사용하면 대부분의 데이터 형식을 유연하게 처리할 수 있지만, 클라이언트가 Content-Type을 올바르게 지정하지 않으면 데이터가 제대로 처리되지 않을 수 있습니다.

 

bodyParser.urlencoded({ extended: true })와 bodyParser.json()을 사용하지 않으면?

요청 본문(body)을 자동으로 파싱하지 않기 때문에 클라이언트에서 보낸 데이터가 req.body에 담기지 않습니다. 이 경우, 클라이언트에서 보낸 데이터를 직접 처리해야 합니다.

1. bodyParser.urlencoded({ extended: true })를 사용하지 않는 경우

  • application/x-www-form-urlencoded 형식의 데이터를 자동으로 파싱하지 않게 됩니다.
  • 클라이언트가 보낸 데이터를 req.body로 바로 접근할 수 없으며, 해당 데이터는 req.body가 아니라 req 객체의 body 필드에 담기지 않습니다.
  • 폼 데이터를 직접 파싱하려면, 쿼리 문자열을 수동으로 처리하거나 다른 방법을 사용해야 합니다.

2. bodyParser.json()을 사용하지 않는 경우

  • application/json 형식의 데이터를 자동으로 파싱하지 않게 됩니다.
  • 클라이언트가 보낸 JSON 데이터를 req.body로 바로 접근할 수 없습니다.
  • JSON 데이터를 파싱하려면, JSON.parse()를 수동으로 호출하거나 다른 방법을 사용해야 합니다.

예시 (bodyParser를 사용하지 않는 경우)

const express = require('express');
const app = express();

app.post('/data', (req, res) => {
  // bodyParser가 없으면 req.body에 접근할 수 없음
  console.log(req.body); // undefined 또는 오류

  // 요청 본문을 수동으로 처리해야 함
  req.on('data', (chunk) => {
    const data = chunk.toString();
    console.log('Received data:', data); // 쿼리 문자열 형태로 출력됨
  });

  req.on('end', () => {
    res.send('Data received!');
  });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

폼 데이터 처리 예시

클라이언트가 보낸 폼 데이터는 쿼리 문자열로 전송되므로, req.on('data')로 처리할 수 있습니다.

name=John&age=30
이 데이터는 req.on('data', callback)로 chunk가 전달되며, 이를 수동으로 파싱하여 객체 형식으로 변환해야 합니다.

JSON 데이터 처리 예시

클라이언트가 보낸 JSON 데이터는 application/json 형식으로 전송됩니다. 이를 수동으로 파싱하려면 req.on('data')와 JSON.parse()를 사용해야 합니다.

{
  "name": "John",
  "age": 30
}
const express = require('express');
const app = express();

app.post('/json', (req, res) => {
  let body = '';

  req.on('data', (chunk) => {
    body += chunk;
  });

  req.on('end', () => {
    const parsedBody = JSON.parse(body); // JSON.parse()로 파싱
    console.log(parsedBody); // { name: 'John', age: 30 }
    res.send('JSON Data received!');
  });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

결과

bodyParser 미들웨어를 사용하지 않으면 요청 본문을 수동으로 처리해야 하기 때문에 코드가 더 복잡해지고 실수가 발생할 확률도 높습니다. bodyParser를 사용하면 요청 본문을 쉽게 파싱할 수 있지만, 이를 사용하지 않으면 요청을 직접 다루어야 하므로, 폼 데이터나 JSON 데이터의 파싱 로직을 직접 구현해야 합니다.