WEB – 간단한 웹 서버 제작

포트번호

클라이언트가 서버에게 요청을 할 때, 특정 프로그램에게 요청을 하려면 해당 프로그램의 주소를 알아야 됩니다. 즉 서버에서 사용하는 프로그램 주소포트 번호를 알아야 됩니다.

  • http 프로토콜로 통신하는 서버 프로그램은 포트 번호 80번을 쓰도록 정해집니다.
  • https프로토콜로 통신하는 서버 프로그램은 포트 번호 443번을 쓰도록 정해집니다.


간단한 서버 만들기

// http코어 모듈을 접근하는 객체 저장
const http=require('http');

// 서버 객체 가져오기 (서버 프로그램 생성) 
// 인수에 적힌 함수로 서버 프로그램의 응답을 처리함 
let server=http.createServer(function(request,response){
  // h1태그를 보내면서 응답을 함  
    response.end('<h1>Hello world!</h1>');
});
// 포트번호:3000, 이 서버 프로그램의 주소는 3000이다.
// 나중에 클라이언트가 3000번을 지정하고 접속하면 됨
server.listen(3000);

http모듈로부터 서버 객체를 가져오고 listen함수로 포트번호를 지정하면 간단하게 나의 PC를 서버로 만들 수 있습니다.

서버 객체를 가져온다는 것은 서버 프로그램 한 개를 생성한다고 생각하면 됩니다.
서버 객체를 가져올 때 인수에 함수를 첨가하는 방식으로 서버 프로그램의 응답을 처리합니다.
위처럼 코딩을 하면, 서버에 요청이 왔을 때 h1태그를 보내면서 응답을 합니다.

서버에 하나의 프로그램(h1태그를 보내는 프로그램)이 생성되었습니다.
이 서버 프로그램의 주소(포트 주소)는 listen함수를 통해 3000으로 지정할 수 있습니다.

위처럼 서버 프로그램을 생성하고 포트 주소도 지정해야 서버로 될 자격 조건을 마칩니다.

위 프로그램의 테스트는 127.0.0.1:3000을 통해 할 수 있습니다.
127.0.0.1자신 컴퓨터를 나타내는 주소로, 개발할 때 테스트용으로 사용됩니다.
주소 뒤에는 콜론과 포트번호를 기재해야 접속이 가능합니니다.
(포트번호를 기재하지 않으면 default로 80포트로 접속합니다.)


URL의 구조

URL(Uniform Resource Locator)인터넷에서 웹 페이지, 이미지, 비디오 등 리소스의 위치를 가리키는 문자열입니다. 사용자는 아래와 같은 URL을 웹 주소창에 입력해서 웹 페이지로 이동합니다.

http://example.com/business/mart/item?category=14&id=2965

위 URL을 기준으로 구조를 설명하겠습니다.

https: 스킴(scheme)으로 프로토콜 이름을 나타냅니다.
(프로토콜: 클라이언트와 서버 간의 통신 규약, 주로 http or https)

example.com: 호스트(host)로 특정 서버를 나타냅니다.

business/mart/item: 경로(path)로 원하는 자원의 위치를 나타냅니다.
(busines/mart디렉토리의 item파일이라고 생각할 수도 있지만, 해당 디렉토리와 파일이 없어도 무관)

  • 위의 Path를 보고 서버는 데이터베이스나 파일에 있는 상품 정보를 응답으로 줄 수 있습니다.
  • 즉 Path에 대해서 어떻게 응답할지는 서버 프로그램을 만드는 사람이 자유롭게 결정합니다.

category=14&id=2965: 쿼리(query)로 서버에 요청할 때 원하는 것을 상세하게 표현하기 위해 사용합니다.
(?키워드 뒤에 기재함)

let url = new URL('http://example.com/business/mart/item?category=14&id=2965');

console.log(url.protocol);
console.log(url.host);
console.log(url.pathname);
console.log(url.search);


url에 따라 다른 응답을 주기(라우팅 하기)

// http코어 모듈을 접근하는 객체 저장
const http=require('http');

users=['Tom','Andy','Jessica','Paul'];

// 서버 객체 가져오기 (서버 프로그램 생성)
// 인수에 적힌 함수로 서버 프로그램의 응답을 처리함
let server=http.createServer(function(request,response){
  // path~query까지 출력함
  console.log(request.url);

  if(request.url === '/'){ // '/'는 url에서 호스트 부분만 입력해도 자동으로 붙음 <path 기재 x>
    response.end('<h1>Welcome!</h1>');
  }
  else if(request.url==='/users'){
    response.end('<h1>'+users+'</h1>');
  }
  else {
    response.end('<h1>Page Not Available</h1>');
  }

});
// 포트번호:3000, 이 서버 프로그램의 주소는 3000이다.
// 나중에 클라이언트가 3000번을 지정하고 접속하면 됨
server.listen(3000);

http모듈 내부에는 request, response객체가 있습니다.

request는 ‘클라이언트가 요청할 때 보낸 정보들이 담긴 객체’입니다.
response는 ‘서버가 응답할 때 클라이언트에게 전송할 정보들이 담긴 객체’입니다.

클라이언트가 서버로 요청할 때는 주로 URL에 정보를 담아서 보냅니다.
request.url을 출력하면 요청한 PC(클라이언트)가 어떤 정보를 담아서 서버에게 요청했는지 확인할 수 있습니다.
해당 명령어는 URL구조에서 path~query까지를 반환합니다.

이 request.url 속성을 조건문으로 이용하면 다음과 같이 다른 응답을 줄 수 있습니다.

request.url이 ‘/users’와 같을 때 서버의 응답입니다.
콘솔창에서는 path까지 출력된 모습입니다. ‘/favion.ico’는 신경쓰지 않아도 됩니다.


request.url이 if문과 else if문에 적힌 조건을 만족하지 않을 때 서버의 응답입니다.
콘솔창에서는 path~query까지 출력된 모습입니다.


응용까지 해보겠습니다.
아래 소스를 else문 위에 붙여 넣기 해주세요!!

  // split험수는 인수에 적힌 문자를 기준으로 문자열울 나누고 배열에 저장해서 반환함
    // '/users'.split('/')을 하면 ['','users']가 반환됨
    // url형식: http://host/users/1
    // 서버는 url의 path 일부만 받아서 처리를 할 것이니 인덱스 1원소만 이용함
    else if(request.url.split('/')[1]==='users'){
      // 이번에는 url의 path다른 부분을 처리를 할 것이니 인덱스 2원소를 이용함 
      let userIdx=request.url.split('/')[2];
      let userName=users[userIdx-1];
      // users배열의 원소를 h1태그로 감싸서 응답함
      response.end('<h1>'+userName+'</h1>');
  }

path의 숫자를 이용해서 응답을 다르게 해보았습니다.
path가 ‘users/1’이면 ‘Tom’을 보내며 응답합니다.
path가 ‘users/4’dlaus ‘Paul’을 보내며 응답합니다.

이러한 기능은 split함수를 이용해서 해결이 가능합니다.
주석을 참조해주세요!


Express 서드 파티 모듈을 사용해서 라우팅하기

Express ‘노드에서 실행될 서버 프로그램을 간편하게 만들 수 있게 해주는 프레임 워크입니다.
(프레임 워크: 애플리케이션 개발에 바탕이 되는 템플릿과 같은 역할을 하는 클래스들과 인터페이스의 집합)

express모듈은 터미널 창에 npm install express 명령어를 입력해서 설치할 수 있습니다.

http모듈을 사용했을 때와 같은 페이지를 Express모듈로 만들어 보겠습니다!

// express 서브파티 모듈을 접근하는 함수를 불러옴
const express=require('express');
// express함수로 express 서브파티 모듈을 접근하는 객체를 불러옴
const app=express();

users=['Tom','Andy','Jessica','Paul'];

// 라우팅 처리 메소드: get
app.get('/',(request,response)=>{
  response.end('<h1>Welcome!</h1>');
});

app.get('/users',(request,response)=>{
  response.end(`<h1>${users}</h1>`);
});

// id라는 문자열을 의미하는 것이 아님
// 이 위치에 오는 값을 id라는 속성에 담으라는 express만의 표기
// id는 request객체의 params객체의 id속성임
app.get('/users/:id',(request,response)=>{
  console.log(request.params);
  const userName=users[request.params.id-1];
  response.end(`<h1>${userName}</h1>`);
});

// *라는 문자열을 의미하는 것이 아님
// 위에서 지정한 path가 아닌 다른 path일 때의 응답을 처리함
app.get('*',(request,response)=>{
  response.end('<h1>Page Not Available</h1>');
});

// 포트번호:3000, 이 서버 프로그램의 주소는 3000이다.
// 나중에 클라이언트가 3000번을 지정하고 접속하면 됨
app.listen(3000);

express모듈을 접근하는 객체는 보통 app으로 생성합니다.

app객체를 이용하면 express모듈의 기능을 가져올 수 있습니다.

대표적으로,
app.get 메소드만 이용하면 라우팅을 할 수 있습니다.

app.get('/',(request,response)=>{
  response.end('<h1>Welcome!</h1>');
});
let server=http.createServer(function(request,response){
  if(request.url === '/'){ // '/'는 url에서 호스트 부분만 입력해도 자동으로 붙음 <path 기재 x>
    response.end('<h1>Welcome!</h1>');
  }

두 소스 모두 path가 없을 때 응답을 처리하는 역할을 합니다.
그러나 app.get을 이용할 때가 훨씬 간결합니다.

app.get('/users/:id',(request,response)=>{
  const userName=users[request.params.id-1];
  response.end(`<h1>${userName}</h1>`);
});
let server=http.createServer(function(request,response){
  if(request.url.split('/')[1]==='users'){
      let userIdx=request.url.split('/')[2];
      let userName=users[userIdx-1];
      response.end('<h1>'+userName+'</h1>');
  }
}

두 소스 모두 path에 적힌 숫자를 이용해서 라우팅 역할을 합니다.
마찬가지로 app.get을 이용했을 때가 훨씬 간결합니다.

후자에서 id는 path에 적힌 문자열을 의미하는 것이 아닙니다.
이 위치(127,0,0,1:3000/users/여기)에 오는 값을 id라는 속성에 담으라는 express만의 표기입니다.
(id는 request객체의 params객체의 id속성)

나머지 소스의 설명은 주석을 참조하시면 충분할 것입니다.


html태그와 변수의 표기법

번외로 html태그와 변수를 같이 표기하는 방법 두 가지를 소개합니다.

response.end('<h1>'+userName+'</h1>');

일반적으로 html태그와 변수를 같이 표기하는 방법입니다.
html태그와 변수를 구분 짓기 위해 작은 따옴표와 ‘+’키워드를 잘 이용해야 됩니다.

  response.end(`<h1>${userName}</h1>`);

변수 여러 개를 같이 표기할 때 유용한 방법입니다.
작은 따옴표를 닫을 필요도 없고 ‘+’키워드도 없습니다.

다만 `키워드로 시작과 끝을 나타내고 변수 주변에는 ${}를 추가해야 합니다!


감사합니다.

Node에 관한 게시물은 CodeIt,생활코딩의 강의 내용을 정리한 글입니다. 강의 이미지나 내용 자체를 업로드하지는 않습니다!!

Leave a Reply

Your email address will not be published. Required fields are marked *