//
Search
🎊

05. NodeJS HTTP 모듈로 서버 만들기 실습

1. 요청과 응답 이해하기

클라이언트와 서버는 요청(Req:Request)와 응답(Res:Response)로 구성 되어있으며, 클라이언트로 요청을 보내고 서버에서는 요청의 내용을 읽고 처리한 뒤 클라이언트에 응답을 보낸다.
즉 서버에는 요청을 받는 부분과 응답을 보내는 부분이 있어야 한다.
요청과 응답은 이벤트 방식이라고 생각
클라이언트로부터 요청이 왔을 때 어떤 작업을 수행할지 이벤트 리스너를 미리 등록해야 함.

/server0.js

const http = require('http'); //http 서버가 있어야 웹 브라우저의 요청을 처리할 수 있으므로 http 모듈을 사용 http.createServer((req, res) => { // 여기에 어떻게 res 할지를 작성을 한다. });
JavaScript
복사
http 서버가 있어야 웹 브라우저의 요청을 처리할 수 있으므로 http 모듈을 사용
http 모듈에는 createServer 메서드가 있다.
인수로 요청에 대한 콜백 함수를 넣을 수 있으며, 요청이 들어올 때마다 매번 콜백 함수가 실행된다. 따라서 이 콜백 함수에 응답을 적으면 된다.
createServer의 콜백 부분을 보면 req와 res 매개변수가 있다.
보통 request를 줄여 req라고 표현하고, response를 줄여 res라고 표현합니다.
req 객체는 요청에 관한 정보들을, res 객체는 응답에 관한 정보들을 담고 있다.
아직은 코드를 실행해도 아무 일도 일어나지 않는다.
상단에 주석 넣는 란에 요청에 대한 응답도 넣어주지 않았고 서버와 연결하지도 않았기 때문
다음 예제에서 응답을 보내는 부분과 서버에 연결하는 부분을 추가해보겠습니다.

/server1.js

const http = require('http'); http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); /* res.writeHead는 응답에 대한 정보를 기록하는 메서드 : 첫 번째 인수로 성공적인 요청임을 의미하는 200을, 두 번째 인수로 응답에 대한 정보를 보내는데 콘텐츠의 형식이 HTML임을 알리고 있다. 또한 한글 표시를 위해 charset을 utf-8로 지정했다. 이 정보가 기록되는 부분을 헤더(Header)라고 부른다. */ res.write('<h1>Hello Node!</h1>'); /* res.write 메서드의 첫 번째 인수는 클라이언트로 보낼 데이터. 지금은 HTML 모양의 문자열을 보냈지만 버퍼를 보낼 수도 있다. 또한, 여러 번 호출해서 데이터를 여러 개 보내도 된다. 데이터가 기록되는 부분을 본문(Body)이라고 부른다. */ res.end('<p>Hello Server!</p>'); /* - res.end는 응답을 종료하는 메서드 만약 인수가 있다면 그 데이터도 클라이언트로 보내고 응답을 종료 */ }) .listen(8080, () => { // 서버 연결 /* createServer 매서드 뒤에 listen메서드를 붙이고 클라이언트에 공개할 포트 번호와 포트 연결 완료 후 실행될 콜백 함수를 넣는다. 이제 이 파일을 실행하면 서버는 8080 포트에서 요청이 오기를 기다린다. */ console.log('8080번 포트에서 서버 대기 중입니다!'); });
JavaScript
복사
상단의 코드를 넣고 node server1를 입력하여 파일을 실행한다.
실행화면
이제 웹 브라우저를 열어 http://localhost:8080 또는 http://127.0.0.1:8080에 접속
재 실습시 포트 충돌날 수 있으니 한번 수정할 것
res 객체에는 res.writeHead와 res.write, res.end 
위의 예제는 res.write에서 <h1>Hello Node!</h1> 문자열을, res.end에서 <p>Hello Server!</p> 문자열을 클라이언트로 보낸 후 응답이 종료함.
브라우저는 응답 내용을 받아서 렌더링한다.

HTTP 상태 코드

200이나 500과 같은 숫자는 HTTP 상태 코드
res.writeHead에 첫 번째 인수로 상태 코드를 넣었는데, 브라우저는 서버에서 보내주는 상태 코드를 보고 요청이 성공했는지 실패했는지를 판단한다.
2XX: 성공을 알리는 상태 코드입니다. 대표적으로 200(성공), 201(작성됨)이 많이 사용됩니다.
3XX: 리다이렉션(다른 페이지로 이동)을 알리는 상태 코드입니다. 어떤 주소를 입력했는데 다른 주소의 페이지로 넘어갈 때 이 코드가 사용됩니다. 대표적으로 301(영구 이동), 302(임시 이동)가 있습니다. 304(수정되지 않음)는 요청의 응답으로 캐시를 사용했다는 뜻입니다.
4XX: 요청 오류를 나타냅니다. 요청 자체에 오류가 있을 때 표시됩니다. 대표적으로 400(잘못된 요청), 401(권한 없음), 403(금지됨), 404(찾을 수 없음)가 있습니다.
5XX: 서버 오류를 나타냅니다. 요청은 제대로 왔지만 서버에 오류가 생겼을 때 발생합니다. 이 오류가 뜨지 않게 주의해서 프로그래밍해야 합니다. 이 오류를 res.riteHead로 클라이언트에 직접 보내는 경우는 거의 없고, 예기치 못한 에러 발생 시 서버가 알아서 5XX대 코드를 보냅니다. 500(내부 서버 오류), 502(불량 게이트웨이), 503(서비스를 사용할 수 없음)이 자주 사용됩니다.

Https

https 모듈은 웹 서버에 SSL 암호화를 추가한다.
GET이나 POST 요청을 할 때 오가는 데이터를 암호화해서 중간에 다른 사람이 요청을 가로채더라도 내용을 확인할 수 없게 한다.
요즘은 로그인이나 결제가 필요한 창에서 https 적용이 필수가 되는 추세
상단의 서버에 암호화를 적용하려면 https 모듈을 사용해야 한다.
하지만 https는 아무나 사용할 수 있는 것이 아니다.
암호화를 적용하는 만큼, 그것을 인증해줄 수 있는 기관도 필요하다.
인증서는 인증 기관에서 구입해야 하며, Let’s Encrypt 같은 기관에서 무료로 발급해주기도 한다.

/server2.js

const https = require('https'); const fs = require('fs'); https.createServer({ cert: fs.readFileSync('도메인 인증서 경로'), key: fs.readFileSync('도메인 비밀키 경로'), ca: [ fs.readFileSync('상위 인증서 경로'), fs.readFileSync('상위 인증서 경로'), ], }, (req, res) => { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('<h1>Hello Node!</h1>'); res.end('<p>Hello Server!</p>'); }) .listen(443, () => { console.log('443번 포트에서 서버 대기 중입니다!'); });
JavaScript
복사
다른 것은 거의 비슷하지만 createServer 메서드가 인수를 두 개 받는다.
두 번째 인수는 http 모듈과 같이 서버 로직이고, 첫 번째 인수는 인증서에 관련된 옵션 객체이다.
인증서를 구입하면 pem이나 crt, 또는 key 확장자를 가진 파일들을 제공한다.
파일들을 fs.readFileSync 메서드로 읽어서 cert, key, ca 옵션에 알맞게 넣으면 된다.
실제 서버에서는 80 포트 대신 443 포트를 사용하면 된다.

Http2

노드의 http2 모듈은 SSL 암호화와 더불어 최신 HTTP 프로토콜인 http/2를 사용할 수 있게 한다.
http/2는 요청 및 응답 방식이 기존 http/1.1보다 개선되어 훨씬 효율적으로 요청을 보냅니다. http/2를 사용하면 웹의 속도도 많이 개선된다.
그림을 보면 http/1.1과 http/2의 차이를 확연하게 느낄 수 있다.
실제로는 http/1.1도 파이프라인이라는 기술을 적용하므로 이렇게 큰 차이는 나지 않는다.
하지만 http/2가 훨씬 효율적인 것만은 분명합니다.

/server3.js

const http2 = require('http2'); const fs = require('fs'); http2.createSecureServer({ cert: fs.readFileSync('도메인 인증서 경로'), key: fs.readFileSync('도메인 비밀키 경로'), ca: [ fs.readFileSync('상위 인증서 경로'), fs.readFileSync('상위 인증서 경로'), ], }, (req, res) => { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('<h1>Hello Node!</h1>'); res.end('<p>Hello Server!</p>'); }) .listen(443, () => { console.log('443번 포트에서 서버 대기 중입니다!'); });
JavaScript
복사
https 모듈과 거의 유사하다.
https 모듈을 http2로, createServer 메서드를 createSecureServer 메서드로 바꾸면 된다.