JavaScript

[JS중급] 초간단 웹서버 만들기

염두리안 2024. 11. 30. 18:46
728x90
반응형
  • 서버와 클라이언트
    • 클라이언트: 서비스에 관한 요청을 서버에 보냄
    • 서버: 클라이언트 요청에 응답함
  • 웹서버 만들기
    • http://127.0.0.1:3000
      • 127.0.0.1 → 개발용 테스트 IP | 외부 다른 컴퓨터가 아닌, 컴퓨터 자기 자신을 나타냄
      • 3000  → 코드에서 지정한 포트 번호
const http = require('http'); // 통신규약

// 서버 객체 생성
// request: 클라이언트 요청에 관한 객체
// response: 서버 객체가 할 응답에 관한 객체
let server = http.createServer(function(request, response){
    response.end('<h1>Hello Wolrd!</h1>');
}); 
server.listen(3000);    // 클라이언트 요청을 3000번 포트로 받아들임

  • 네트워크 지식
    • 프로토콜: 클라이언트-서버가 서로 통신하기 위해 사용하는 규약
    • 포트번호: 클라이언트가 서버에 요청을 보낼 때, 서버에서 실행되고 있는 여러 프로그램중 어느 프로그램과 통신할 것인지 나타내기 위해 지정하는 번호
  • URL의 구조
    • Uniform Resource Locator: 웹 상의 특정 자원의 위치를 나타낸 문자열
    • http://example.com/business/mart/item?category=14&id=2965
      • http : 스킴(scheme) → 프로토콜 이름 | 클라이언트-서버 간의 통신 규약
      • example.com : 호스트(host) → 특정 서버를 나타냄 | 127.0.0.1 같은 IP 주소를 넣어도 됨
        • 도메인 네임 : 문자열로만 하나의 서버를 특정하는 것... 수많은 영역을 추상적으로 나타내기 위해 사용
        • 루트 도메인 : 인터넷 전체를 나타내는 단위 | google.com → google.com.
        • TLD(Top-Level Domain) : 루트 도메인 하위 | 사이트가 속한 국가 또는 사이트가 제공하는 서비스의 카테고리를 나타냄 | .kr .jp .net 같은거
        • SLD(Second-Level Domain) : TLD 하위 | www.google.co.kr 에서 google이 SLD
      • /business/mart/item : 경로(path) → 하나의 서버 안에서 원하는 자원의 위치를 나타냄 | 의미를 나타내기 위한 용도이므로, 디렉토리 구조 안에 item 파일이 없어도 됨
      • ?category=14&id=2965 : 쿼리(query) → 서버에 요청할 때 원하는 것을 상세히 표현하기 위해 사용
    • Domain Name Resolution의 원리
      • 브라우저에서 도메인 네임만으로도 특정 컴퓨터와 통신할 수 있는 것은 본격적인 통신을 시작하기 전, 도메인 네임을 IP주소로 변환해주는 절차가 존재하기 때문임
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);    // 쿼리

>> http:
>> example.com
>> /business/mart/item
>> ?category=14&id=2965
  • 라우팅 해보기
const http = require('http');
let server = http.createServer(function(request, response){
    console.log(request.url);
}); 
server.listen(3000);

// http://127.0.0.1:3000/users 접속시 /users 출력
const http = require('http');

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

let server = http.createServer(function(request, response){
    if(request.url === '/'){
        response.end('<h1>Welcome!</h1>');
    } else if(request.url === '/users'){
        response.end('<h1>' + users + '</h1>');
    } else {
        response.end('<h1>Page Not Available</h1>');
    }
}); 
server.listen(3000);

  • http 모듈로 라우팅 시 불편함
// split 원리 보기
>> node
> '/users/1'.split('/');
>> [ '', 'users', '1' ]
const http = require('http');

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

let server = http.createServer(function(request, response){
    if(request.url === '/'){
        response.end('<h1>Welcome!</h1>');
    } else if(request.url === '/users'){
        response.end('<h1>' + users + '</h1>');
    } else if(request.url.split('/')[1] === 'users') {
        // 1번 문자열에 users가 있는지 확인하는 if문
        // url: /users/1, /users/2, ..
        let userIdx = request.url.split('/')[2];
        let userName = users[userIdx - 1];
        response.end('<h1>' + userName + '</h1>');
    } else {
        response.end('<h1>Page Not Available</h1>');
    }
}); 
server.listen(3000);

  • 권장하는 스타일로 코딩하기
// Arrow Function 형태 + 변수는 최대한 상수로 바꾸기
const http = require("http");
const users = ['Tom', 'Andy', 'Jessica', 'Paul']; // const

const server = http.createServer((request, response) => { // Arrow Function, const
  if (request.url === '/') {
    response.end('<h1>Welcome!</h1>');
  } else if (request.url === '/users') {
    response.end('<h1>' + users + '</h1>');
  } else if (request.url.split('/')[1] === 'users') {
    //url : /users/1, /users/2, ..
    const userIdx = request.url.split('/')[2]; // const
    const userName = users[userIdx-1]; // const
    response.end('<h1>' + userName + '</h1>');
  } else {
    response.end('<h1>Page Not Available</h1>');
  }
});
server.listen(3000);
// response.end('<h1>' + userName + '</h1>'); 보다는
response.end(`<h1>${userName}</h1>`);
// 최종
const http = require("http");
const users = ['Tom', 'Andy', 'Jessica', 'Paul']; // const

const server = http.createServer((request, response) => { // Arrow Function, const
  if (request.url === '/') {
    response.end('<h1>Welcome!</h1>');
  } else if (request.url === '/users') {
    response.end(`<h1>${users}/h1>`); // Template String
  } else if (request.url.split('/')[1] === 'users') {
    //url : /users/1, /users/2, ..
    const userIdx = request.url.split('/')[2]; // const
    const userName = users[userIdx-1]; // const

    response.end(`<h1>${userName}</h1>`); // Template String
  } else {
    response.end('<h1>Page Not Available</h1>');
  }
});

server.listen(3000);
  • express 모듈로 하는 더 세련된 라우팅
    • Express : node.js에서 실행될 서버 프로그램을 간펴하게 만들 수 있게 해주는 프레임워크 | 서드 파티 모듈
// express  설치
npm install express
const http = require('http');
const express = require('express');     // express 모듈 로드
const app = express();      // express 객체에 보통 app이라는 이름을 붙임
users = ['Tom', 'Andy', 'Jessica', 'Paul'];

app.get('/', (request, response) => {
    response.end('<h1>Welcome!</h1>');
});
app.get('/users', (request, response) => {
    response.end(`<h1>${users}</h1>`);
});
// /:id -> 이 위치에 들어오는 값을 id라는 속성에 담아라!
app.get('/users/:id', (request, response) => {
    const userName = users[request.params.id - 1];
    response.end(`<h1>${userName}</h1>`);
});
// *: 나머지 url... path가 들어가야 할 자리에 들어간 모든 패스
app.get('*', (request, response) => {
    response.end('<h1>Page Not Available</h1>');
});

app.listen(3000);

 

728x90
반응형