Mini Node Server 스프린트2 - express 사용하기
스프린트 과제 설명
- 스프린트 1과 동일
- Express 공식문서 활용 : https://expressjs.com/ko/
문제 해결 코드
1. express를 적용하여 초기값 설정
const express = require('express')
const cors = require('cors')
const app = express()
const PORT = 5000;
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
})
2. 미들웨어 적용
app.use(cors())
// 응답(response)에 자동으로 cors 헤더 입력
app.use(express.json({strict: false}))
// JSON으로 된 요청바디(request body)를 파싱해서 받아옴
3. 요청 메소드에 따른 응답 적용
app.get('/', (req, res) => {
res.send()
})
app.post('/upper', (req, res) => {
res.json(req.body.toUpperCase())
})
app.post('/lower', (req, res) => {
res.json(req.body.toLowerCase())
})
에러 핸들링
1. 응답(response)의 Content-Type을 application/json이 아닌 text/html로 전달
- SyntaxError: Unexpected token " in JSON at position 0
// 에러코드
app.use(express.json())
- 문제상황 : express.json() 메소드를 통해서 요청 바디의 JSON을 Parse하지 못함
- 원인 : 디폴트 옵션으로 인해 해당 메소드는 배열과 객체 데이터만 Parse 해줌
- express.json([options]) 메소드에서 options 부분을 입력하지 않으면 기본값인 {strict:true}가 입력되어, 객체와 배열 데이터에만 메소드가 작동함
- 그러나 현재 app.js 파일에서는 원시 데이터 타입으로 요청바디 자료를 받기 때문에 해당 메소드가 동작하지 않음
Property | Description | Type | Default |
strict | Enables or disables only accepting arrays and objects; when disabled will accept anything JSON.parse accepts |
Boolean | true |
(링크 : https://expressjs.com/en/4x/api.html)
// app.js 파일에서 요청바디(request body)의 데이터를 전달받는 코드
post(path, body) {
fetch(`http://localhost:5000/${path}`, {
method: 'POST',
body: JSON.stringify(body), // 요청바디 데이터를 원시 데이터 타입으로 받음
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(res => {
this.render(res);
});
}
- 해결방안 1 : 메소드의 괄호 안에 {strict:false}를 입력하여, 배열과 객체뿐 아니라 원시 데이터 타입도 parse 시켜주도록 변경
// 해결방안 1 코드
app.use(express.json({strict: false}))
- 해결방안 2 : App.js 파일에서 요청바디를 받을 때부터 객체 형태로 받아 서버로 전달해주기
// 해결방안 2 코드
// App.js 파일의 내용 변경
post(path, body) {
fetch(`http://localhost:5000/${path}`, {
method: 'POST',
body: JSON.stringify({text : body}), // 변경한 부분
headers: {
'Content-Type': 'application/json'
}
})
then(res => res.json())
.then(res => {
this.render(res);
});
}
// basic-sever.js 파일의 내용 변경 (body가 'text'라는 key를 갖는 객체이므로 그에 따라 수정)
app.post('/upper', (req, res) => {
res.json(req.body.text.toUpperCase())
})
app.post('/lower', (req, res) => {
res.json(req.body.text.toLowerCase())
})
2. res.send() 메소드 사용시, 에러는 없지만 브라우저에 응답 표시가 안됨
- 문제상황 : 응답(response)의 Content-Type을 application/json이 아닌 text/html로 전달
// 문제 발생 코드
app.post('/upper', (req, res) => {
res.send(req.body.toUpperCase())
})
app.post('/lower', (req, res) => {
res.send(req.body.toLowerCase())
})
- 원인 : JSON 타입으로 응답을 전달해야 하지만, res.send()는 텍스트 형식으로 데이터를 전달함
- 해결방안 1 : JSON.stringfy(value) 메소드로 데이터를 JSON 형식으로 바꿔주고,
헤더의 Content-Type에 application/json 기재하기
// 해결방안 1 코드
app.post('/upper', (req, res) => {
res.set('Content-Type', 'application/json') // 헤더의 Content-Type 설정
res.send(JSON.stringify(req.body.toUpperCase())) // 데이터를 JSON 타입으로 전달
})
app.post('/lower', (req, res) => {
res.set('Content-Type', 'application/json') // 헤더의 Content-Type 설정
res.send(JSON.stringify(req.body.toLowerCase())) // 데이터를 JSON 타입으로 전달
})
- 해결방안 2 : res.json() 메소드 사용
// 해결방안 2 코드
app.post('/upper', (req, res) => {
res.json(req.body.toUpperCase()) // res.json() 메소드 사용
})
app.post('/lower', (req, res) => {
res.json(req.body.toLowerCase()) // res.json() 메소드 사용
})
- 코멘트
- '응답(Response)으로 전달되는 실제 데이터의 유형'과 '헤더의 Content-Type에서 표시하는 데이터 유형'은 다르게 표시될 수 있음
- 이는 혼란을 줄 수 있기 때문에 헤더에 Content-Type을 정확하게 작성해야 함
- res.json() 메소드 : 받은 인자를 json 문자열로 변환해서 헤드에 'Content-Type : application/json' 으로 셋팅해주고, body인자에 저장해서 res.send()를 호출해 body를 인자로 넘겨줌
'프로그래밍 > 웹 개발' 카테고리의 다른 글
[React] useState Hook과 Props로 쇼핑몰 상태관리 (1) | 2021.08.22 |
---|---|
[React] Hook과 Styled Component를 통한 기능 구현 (0) | 2021.08.21 |
[Node.js] MySQL과 연동하여 서버 및 DB 구축하기 (0) | 2021.07.28 |
[Node.js] dontev 모듈과 .env를 사용하여 sql 비밀번호 숨기기 (0) | 2021.07.27 |
[Node. js] Mini Node Server 제작 스프린트 (createServer) (0) | 2021.07.01 |
댓글