개발자공부일기
Node.js 2일차 본문
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
처리 과정:
- bodyParser.urlencoded()가 작동하여 쿼리 문자열을 파싱합니다.
- 결과:
req.body = { name: 'John', age: '30' };
주의사항:
- 데이터를 key=value 형식으로 보내야 하며, JSON 데이터는 제대로 파싱되지 않습니다.
2. bodyParser.json()이 처리하는 데이터
요청 데이터 예시:
- Content-Type: application/json
- 요청 본문:
{ "name": "John", "age": 30 }
처리 과정:
- bodyParser.json()가 작동하여 JSON 본문을 파싱합니다.
- 결과:
req.body = { name: 'John', age: 30 };
주의사항:
- application/json이 아닌 다른 Content-Type으로 요청하면, JSON 본문이 제대로 처리되지 않습니다.
3. 둘 다 선언된 경우 처리 방식
Express는 미들웨어를 순서대로 실행합니다. Content-Type에 따라 적절한 미들웨어가 선택적으로 작동합니다.
요청 처리 흐름:
- 요청:
- 클라이언트는 HTTP 요청의 Content-Type 헤더를 포함시켜 데이터를 보냅니다.
- 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 데이터의 파싱 로직을 직접 구현해야 합니다.
'TIL(Today I Learned)' 카테고리의 다른 글
1주차 서버와 클라이언트/ 웹 어플리케이션서버와 게임서버 (0) | 2024.11.20 |
---|---|
Node.js 간단한 메모장 만들기 (0) | 2024.11.20 |
Node.js 1일차 (0) | 2024.11.18 |
정렬 알고리즘(버블/삽입/선택) (0) | 2024.11.15 |
개인과제 4일차(트러블 슈팅) (0) | 2024.11.14 |