본문 바로가기
프로그래밍/웹 개발

[Node.js] Mini Node Server 스프린트2 (express 사용)

by 제이콥J 2021. 7. 2.

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를 인자로 넘겨줌
반응형

댓글