Mini Node Server 스프린트
스프린트 과제 설명
1. 목적
- 웹 서버를 구현하기
- 클라이언트의 액션(버튼 클릭)에 따라 각기 다른 HTTP 요청을 서버로 보내고, HTTP 요청에 담아 보낸 단어를 소문자 또는 대문자로 변경된 단어를 응답으로 받아 화면에 보여주기
2. 방법
- HTTP 요청과 응답을 다루기 위해 HTTP 모듈 사용
- HTTP 트랜잭션 해부에 관한 공식문서 참고하기 : https://nodejs.org/ko/docs/guides/anatomy-of-an-http-transaction/
3. 요구사항
- Endpoint(URL)에 따른 Method 기능 구현하기
/lower | POST | 문자열을 소문자로 만들어 응답해야 합니다 |
/upper | POST | 문자열을 대문자로 만들어 응답해야 합니다 |
- POST에 문자열을 담아 요청을 보낼 때는 HTTP 메시지의 body(payload)를 이용
- 서버는 POST 요청 이외의 다른 모든 요청에 대하여, 클라이언트에 잘못된 요청이라고 알려주기
- CORS 관련 헤더를 OPTIONS 응답에 적용하기 (클라이언트의 preflight request 에 대한 응답을 돌려주기)
4. 초기 코드
const http = require('http');
const PORT = 5000;
const ip = 'localhost';
const server = http.createServer((request, response) => {
// 코드 작성
response.writeHead(200, defaultCorsHeader);
response.end('hello mini-server sprints');
});
server.listen(PORT, ip, () => {
console.log(`http server listen on ${ip}:${PORT}`);
});
const defaultCorsHeader = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Accept',
'Access-Control-Max-Age': 10
};
문제 해결 코드
1. 메소드가 OPTIONS인 경우, preflight request에 대한 응답 돌려주며 CORSE 관련 헤더를 응답하기
if (request.method === 'OPTIONS') {
response.writeHead(200, defaultCorsHeader);
response.end();
}
2. 메소드가 POST인 경우, url이 각각 '/upper', '/lower'인 경우에 따라 요청 바디 받기
else if (request.method === 'POST') {
response.writeHead(201, defaultCorsHeader);
if (request.url === '/upper') {
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString().toUpperCase();
response.end(body)
});
}
else if (request.url === '/lower') {
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString().toLowerCase();
response.end(body)
});
};
}
3. 위 조건에 해당하지 않는 경우 에러메세지 전달
else {
response.writeHead(404, defaultCorsHeader);
response.end('Bad Request')
}
에러 핸들링
1. if문 2개 실행시 에러 발생
- (에러코드) code : 'ERR_STREAM_WRITE_AFTER_END'
- 문제상황 : if문을 2개 사용하자 에러 코드 발생
- 해결방법 : 조건문 안에 조건문을 넣어주어 if문을 하나로 만들어줌
- 코멘트 : 첫번째 if문과 마지막 else문에 모두 해당되어, 각기다른 2가지의 응답(reponse)을 동시에 발송해서 충돌이 일어남
//에러 수도코드
if (Method==='OPTIONS') { 내용 }
if (Method==='POST' && URL=== '/upper') { 내용 }
else if (Method==='POST' && URL=== '/lower') { 내용 }
else {내용}
// 에러 해결한 코드
if (Method==='OPTIONS') { 내용 }
else if (Method==='POST') {
if (URL=== '/upper') { 내용 }
else if (URL=== '/lower') { 내용 }
}
else {내용}
2. Node.js의 비동기 처리방식으로 인한 에러
- (에러코드1) code: 'ERR_INVALID_ARG_TYPE'
- (에러코드2) TypeError: body.toUpperCase is not a function
- 문제상황 : response에서 body의 데이터를 수정하려고 했으나, 비동기적 처리방식으로 인해 body가 빈 배열
// 에러코드1
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString().toUpperCase();
});
response.end(body)
// 에러코드2
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
});
response.end(body.toUpperCase())
- 해결방법 : request.on의 콜백함수 안에 response.end를 넣어줌
//해결방법1
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
response.end(body.toUpperCase())
});
//해결방법2
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString().toUpperCase();
response.end(body)
});
- 코멘트
- 비동기 처리방식에서 나타나는 현상
- request 구문을 실행시키지만, 실행이 완료되길 기다리지 않고 다음 구문으로 넘어감
- 따라서 request구문 밖의 body에는 여전히 빈 배열이 그대로 전달됨
- 컴퓨터 언어의 공통점은 위에서부터 순차적으로 코드를 읽어나가며, 자바스크립트는 인터프리터 언어로 컴파일 언어와 달리 실행속도 느림
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
console.log(body) // 엘리먼트가 포함된 배열 출력
});
console.log(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 스프린트2 (express 사용) (0) | 2021.07.02 |
댓글