TODO
클라이언트의 액션(버튼 클릭)에 따라 각기 다른 HTTP 요청을 서버로 보내고, HTTP 요청에 담아 보낸 단어를 소문자 또는 대문자로 응답을 받아 화면에 보여 주려 한다.
조건
Endpoint(URL) | Method | 기능 |
/lower | POST | 문자열을 소문자로 만들어 응답해야 합니다 |
/upper | POST | 문자열을 대문자로 만들어 응답해야 합니다 |
•
POST에 문자열을 담아 요청을 보낼 때는 HTTP 메시지의 body(payload)를 이용한다.
•
서버는 요청에 따른 적절한 응답을 클라이언트로 보내야 한다.
•
CORS 관련 헤더를 OPTIONS 응답에 적용해야 한다.
•
클라이언트의 preflight request에 대한 응답을 돌려줘야 한다.
•
preflight request에 대한 응답 헤더는 이미 작성되어 있다.
서버 실행
해당 디렉토리로 진입한 다음, 아래 커맨드를 CLI에 입력하고, 서버를 종료하려면 Ctrl+C를 눌러 프로그램을 강제 종료한다.
node server/basic-server.js
Shell
복사
# 1. nodemon 설치
npm install nodemon
# 2. package.json의 "scripts"에 아래 코드를 추가
"start": "nodemon server/basic-server.js"
# 3. 이후 서버 실행 시 npm start만 입력하면 된다.
Shell
복사
클라이언트 실행
npx serve -l 포트번호 client/
Shell
복사
내 코드 1 : 요청 body에서 문자열 선언
const http = require('http');
const PORT = 4999;
const ip = 'localhost';
const server = http.createServer((request, response) => {
// CORS 관련 헤더를 OPTIONS 응답에 적용
// Method가 OPTIONS인지 분기
if (request.method === 'OPTIONS') {
response.writeHead(200, defaultCorsHeader);
response.end();
}
// Method가 POST라면 url 확인 후 알맞은 요청을 보내주기
if (request.method === 'POST') {
// Method가 POST고 url이 /lower라면
if(request.url === '/lower') {
// 빈 문자열 선언
let data = '';
request.on('data', chunk => {
data = data + chunk;
});
request.on('end', () => {
data = data.toLowerCase();
// 소문자로 된 응답을 돌려주기
response.writeHead(201, defaultCorsHeader);
response.end(data);
});
// Method가 POST고 url이 /upper라면
} else if (request.url === '/upper') {
let data = '';
request.on('data', chunk => {
data = data + chunk;
});
request.on('end', () => {
data = data.toUpperCase();
// 대문자로 된 응답을 돌려주기
response.writeHead(201, defaultCorsHeader);
response.end(data);
});
// 위 두 가지 경우 모두 아니라면
} else {
// 에러로 응답하기
response.writeHead(404, defaultCorsHeader);
response.end();
}
}
});
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
};
JavaScript
복사
내 코드 2 : 요청 body에서 배열 선언
const http = require('http');
const PORT = 4999;
const ip = 'localhost';
const server = http.createServer((request, response) => {
// CORS 관련 헤더를 OPTIONS 응답에 적용
// Method가 OPTIONS인지 분기
if (request.method === 'OPTIONS') {
// 클라이언트의 preflight request에 대한 응답
response.writeHead(200, defaultCorsHeader);
response.end();
}
// Method가 POST라면 url 확인 후 알맞은 요청을 보내주기
if (request.method === 'POST') {
// PUT request body(payload) ------------------
// 빈 배열로 선언
let body = [];
request
// 'data'에 이벤트 리스너 등록해 데이터 받기
.on('data', (chunk) => {
// body 배열에 chunk를 담기
body.push(chunk);
})
// 'end'에 이벤트 리스너 등록해 데이터 받기
.on('end', () => {
// 'data' 이벤트에서 발생시킨 청크 Buffer(문자열 데이터)를 배열에 수집 후
// end 이벤트에서 이어 붙이고 문자열로 만들기
body = Buffer.concat(body).toString();
response.writeHead(201, defaultCorsHeader);
// Method가 POST고 url이 /lower라면
if (request.url === '/lower') {
// 소문자로 된 응답을 돌려주기
response.end(body.toLowerCase());
// Method가 POST고 url이 /upper라면
} else if (request.url === '/upper') {
// 대문자로 된 응답을 돌려주기
response.end(body.toUpperCase());
// 위 두 가지 경우 모두 아니라면
} else {
// 에러로 처리할 것
response.writeHead(404, defaultCorsHeader);
response.end();
}
});
}
});
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,
};
JavaScript
복사
결과 화면
대문자를 입력하면 소문자로, 소문자를 입력하면 대문자로 나와야 하며, 개발자 도구에서도 에러 없이 잘 띄워지면 성공이다.
배운 점
처음에는 HTTP 트랜잭션 해부에 나와있는 대로 배열을 선언하는 방법을 사용했는데, 이유는 모르겠지만 메소드도 안 뜨고 에러가 떠서 문자열을 선언하는 방법으로 변경해 시도했더니 성공했다.
다 끝내놓고 원인을 알았는데, nodemon을 설치하면 처음부터 서버 실행을 따로 안해도 되는 줄 알았던 것이다. nodemon을 설치한 이유는 코드를 수정할 때마다 node server/basic-server.js로 서버를 실행하지 않아도 되고, 처음에 npm start만 입력해도 코드 수정과 동시에 서버를 실행할 수 있다는 것이었다.
코드는 다 써놓고 서버 실행 방법에 익숙하지 않아 날려버린건 매우 안타까웠던 일... 하지만 결과적으로는 코드 한 줄 한 줄 더 자세히 뜯어보고, HTTP 트랜잭션 해부 가이드도 더 자세히 읽어보고, 두 가지 방법을 사용하면서 이해가 잘 되었다. 오늘의 시행착오가 결코 헛되지 않았다.