[데브코스] 프론트엔드 엔지니어링 TIL(2일차)

홍건우·2023년 6월 5일
0

데브코스

목록 보기
2/17
post-thumbnail

네트워크 기초

브라우저에 URL을 입력하면 발생하는 일

  1. URL 해석

    • URL의 구조: scheme://:@:/
      • //은 생략 가능
  2. DNS(Domain Name System) 조회

    • DNS는 도메인과 IP 주소를 서로 변환
    • DNS로 요청을 보내기 전에 브라우저 캐시와 로컬 컴퓨터의 hosts파일을 참조
      • 브라우저 캐시나 hosts에 이미 정의가 되있다면 내부적으로 IP를 반환
      • 정의가 되어있지 않다면 DNS 호출
    • DNS를 운영하는 서버를 Name Server라고 함
    • presnet.do, www.present.do, gateway.dev.present.do
      전부 도메인은 present.do, 나머지 서브 도메인이 붙는 경우는 host라고 함

    스크린샷 2023-06-02 오후 4.30.20.png

  3. 해당 IP가 존재하는 서버로 이동

    • 네트워크 장비 라우터를 통해 이동하며 동적 라우팅을 통해 이동한다.
  4. ARP(Address Resolution Protocol)를 이용하여 MAC 주소 변환

    • 논리 주소인 IP 주소를 물리주소인 MAC 주소로 변환하는 프로토콜
    • 실제 통신을 위해 고유한 MAC 주소가 필요(MAC 주소를 통해 기계의 실제 위치를 알 수 있다.)
    • 네트워크 내에 ARP를 Broadcasting하면 해당 IP 주소를 가지고 있는 기기가 MAC주소를 반환
    • 논리적인 주소와 물리적인 주소를 나눈 이유
      • 논리적 주소 = 도로명 주소, 물리적 주소 = GPS 좌표로 생각하자
      • IP는 대역을 통해 범위를 좁혀나가는 용도로 사용
      • MAC은 실제 위치를 알아내는데 사용
  5. TCP 통신을 통해 Socket을 연다.

    • 네트워크를 통해 해당 기기로 패킷을 전달
    • 3 way handshake 연결 요청
    • 요청이 수락되면 기기는 패킷을 받아 처리
  6. 서버가 응답을 반환

    • HTTP 프로토콜로 들어온 패킷을 읽고 처리
    • 요청에 따른 적절한 응답 값 반환
  7. 브라우저가 렌더링함

    • HTML을 읽어 DOM Tree를 구축
    • 만들어진 DOM Tree를 이용하여 화면에 그림
    • 스크립트 실행

HTTP와 HTTPS의 차이

  • HTTP(HyperText Tranfer Protocol)
  • HTTPS(Hypertext Transfer Protocol Secure)

이름에서 알 수 있듯이 HTTP는 암호화되지 않은 통신을 사용하고 HTTPS는 암호화된 통신을 사용한다.

HTTPS

  • SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security) 프로토콜을 사용하여 데이터를 암호화 ⇒ 데이터의 기밀성과 무결성을 보호하고 제3자가 데이터를 엿보는 것을 방지
  • 443번 포트를 사용(HTTP는 80번 포트 사용)
  • 암호화된 연결을 설정하기 위해 인증서를 사용
    • 인증서를 통해 웹 사이트의 신원을 확인하고, 클라이언트와 서버 간의 통신에 대한 암호화를 제공한다.
    • 인증서는 신뢰할 수 있는 인증 기관(Certificate Authority)에 의해 발급됨
  • SEO(Search Engine Optimization, 검색 엔진 최적화)
    • HTTPS를 사용하는 웹 페이지는 검색 엔진에 의해 보다 긍정적으로 평가됨

HTTPS의 통신 과정

HTTPS는 기존의 HTTP 통신 위에 SSL/TLS 프로토콜을 추가하여 암호화와 인증을 제공함

  • 클라이언트와 서버 간에 SSL/TLS handshake가 이루어짐 ⇒ 이 과정에서 서버의 인증서 확인, 클라이언트와 서버 간의 암호화 알고리즘 및 암호 키 교환 등이 이루어짐

컴퓨터 시간 동작 원리

시간이 결정되는 기준

물리 법칙에 따른 표현

  • 물리량: 시간은 물리학 관점에서 봤을 때 시간과 시각 사이 간격을 표현하는 단위를 뜻함
  • 위치: 시간은 위치에 따라 다르게 표현될 수 있음(나라, 지역마다 시간이 다름)
  • 천문 현상: 지구 자전 속도의 불규칙성, 자전주기와 공전주기 등 천문 현상으로 인한 시간 보정이 필요

협의에 따른 표현

  • 문화: 문화에 따라 시간 표현이 달라짐(태양력, 태음력 등)
  • 역사: 역사적 사건에 의해 시간은 다르게 표현될 수 있음
  • 사회: 사회적 제도에 의해 시간이 변할 수 있음(Summer Time)

협정 세계시(UTC)

  • 원자 시계와 윤초 보정을 기반으로 표준화한 시각
  • 모든 시간대는 UTC+0을 기준으로 환산
  • 표기법은 ISO 8601을 따름

컴퓨터가 시간을 표현하는 방법

  • 하드웨어의 시스템 클럭을 이용
  • 시스템 시간: 특정 시간(Epoch)를 기준으로 시스템 클럭의 틱을 세는 것으로 구현
  • 타임스탬프(Timestamp): 시스템 시간을 값으로 표현한 것

시스템 클럭

  • RTC(Real Time Clock)라는 모듈을 사용함
  • RTC는 메인보드에 붙어있어 전원을 끄더라고 계속 작동
  • RTC는 카운터 회로를 통해 클럭을 발생시킴

컴퓨터가 시간을 알아내는 법

  • 시스템 시간을 네트워크 타임 프로토콜(NTP)를 통해 동기화 할 수 있음
  • NTP 서버에 네트워크 요청을 하여 현재 시간을 받을 수 있음
  • NTP 서버는 계층으로 이루어져 있으며 그 계층을 Stratum이라고 함
  • 최상위 계층을 PRC(Primary Reference Clock)이라고 함

컴퓨터가 시간대를 고려하는 방법

  • Time Zone 데이터를 이용
  • 현실 세계에 이벤트가 발생되면 업데이트 됨
  • 표기법
    • 대륙/도시 형태를 따른다. ex) Asia/Seoul
    • 하나의 값을 ZoneId라고 한다.

시간을 어떤 기준으로 사용해야 할까?

글로벌 서비스 같은 경우 시간이 매우 중요해짐 ⇒ 서비스에서 사용되는 시간을 용도에 맞춰서 기록할 필요가 있음

  • 순수한 시간: 시간대와 지역, 문화, 사회를 고려하지 않고 순수하게 시간을 기록하는 경우(ex 생일, 기념일 등)
  • UTC: 역사, 사회, 문화에 대한 맥락 없이 사건이 발생한 시각만을 고려할 때 사용(ex 로깅, 감사, 시계열 데이터)
  • Time Zone이 적용된 시간: 역사, 사회, 문화를 고려하여 사용자가 이용한 시각을 정확히 알아햐할 때 사용(UI에 표시되는 시간을 사용자 기준으로 보여줄 때 사용, ex 결제 시각, 푸시 알림 시간, 캘린더)

JS에서는 Date 객체나 date-fns, luxon 라이브러리를 사용할 수 있음

암호화

  • 암호화: 평문을 해독할 수 없는 암호문으로 변환하는 것을 말함
    • 단방향(해싱)과 양방향이 존재함

단방향 암호화

  • 한 방향으로만 이루어지는 암호화 알고리즘
  • 해시 알고리즘을 이용함(MD5, SHA)
  • 사용자 비밀번호 등을 저장할 때 자주 사용함
  • MD5, SHA-0, SHA-1은 해시 충돌 가능성이 있어 사용을 권하지 않음

고려할 점

  • 복호화가 불가능하지만 Rainbow Table을 통해 원문을 알아낼 가능성이 있음 ⇒ 불의의 사고로 암호화된 데이터를 탈취당하더라도 원문을 알아 낼 수 없도록 조치를 해야함
    • Rainbow Table: 평문과 해시 함수로 만든 문자열을 모두 저장시켜 놓은 표
  • Salt, Key stretching를 이용하여 해결함
    • Salt: 평문에 임의의 문자열을 추가하여 암호하 하는 방법, 128bit 이상으로 만드는 것이 좋고 사용자마다 다른 Salt를 사용하면 보안성이 높아짐
    • Key stretching: 해시를 여러번 반복하여 원문을 알기 힘들게 만드는 방법, 일반적인 시스템에서 0.2초이상 반복되면 안전함

양방향 암호화

  • 평문을 복호화 할 수 있는 형태로 암호화하는 방법
  • 대칭키와 비대칭키 알고리즘으로 나뉨
    • 대칭키 암호 알고리즘: 대표적으로 AES가 있음, 같은 키를 이용하여 암호화, 복호화가 가능
    • 비대칭키 알고리즘: 대표적으로 RSA가 있음, 공개키와 개인키 두 가지 키가 존재, 소인수 분해를 기반으로 만들어진 알고리즘

함수형 프로그래밍의 특징

장점

  • 상태가 없기 때문에 사이드 이펙트가 없음
  • 높은 재사용성
  • 코드가 짧고 간결함

단점

  • 상태가 없기 때문에 상태 조작이 쉽지 않음
  • 재사용을 위해 함수를 나눠야하고 많은 함수들이 생길 수 있음

객체지향의 오해

  • 객체지향은 패러다임일 뿐 언어와는 관계가 없음 → 언어는 지향하는 것을 조금 더 편하게 구현할 수 있도록 도와줄 뿐, 따라서 클래스가 없는 언어로도 객체지향 프로그래밍을 할 수 있음
  • JS는 프로토타입을 통해 객체지향을 표현함
  • 절차지향, 객체지향 중 우위가 없는 것은 없음
    • 간단한 프로그램일 수록 절차지향이 더 쉽고 직관적임
    • 객체지향은 객체간 통신하기 때문에 흐름이 더 직관적이어서 더 복잡한 프로그램에 적합함

JS의 객체 생성 방법

  1. 객체 리터럴

    const Person = {
      name: 'GunWoo',
      move: function() {
        console.log("이동합니다.");
      },
    }
  2. Object

    const person = new Object();
    person.name = "GunWoo";
    person.move = function () {
      console.log("이동합니다.");
    };
  3. 생성자 함수

    function Person(name) {
      this.name = name;
      this.move = function () {
        console.log("이동합니다.");
      }
    }

프로토타입

  • 객체 지향 프로그래밍에서 객체 간의 상속과 프로퍼티 공유를 구현하는 메커니즘
  • JavaScript 객체는 내부적으로 prototype이라는 프로퍼티를 가지고 있는데 prototype은 해당 객체의 프로토타입 객체를 가리킴
  • 프로토타입 객체 역시 자체적으로 prototype을 가지며, 이를 통해 다른 프로토타입과 연결되는 프로토타입 체인을 형성함
  • 프로토타입 체인은 객체가 특정 프로퍼티나 메소드를 찾을 때, 해당 객체의 프로토타입에도 없으면 상위 프로토타입으로 이동하여 계속해서 찾는 동작을 수행
  • 함수 객체가 생성자 함수로 사용될 때, 해당 함수의 prototype 프로퍼티에 정의된 프로퍼티와 메소드는 생성된 객체들이 상속받게 됨. 즉, prototype은 객체 생성자 함수의 프로토타입 객체를 가리킴

프로토타입이 필요한 이유

  • prototype을 사용하지 않은 경우 ⇒ move함수가 중복되어 메모리가 낭비된다.
function Person(name) {
  this.name = name;
  this.move = function () {
    console.log("이동합니다.");
  }
}

const p1 = new Person('gun');
const p2 = new Person('woo');
console.log(p1); // Person { name: 'gun', move: [Function (anonymous)] }
console.log(p2); // Person { name: 'woo', move: [Function (anonymous)] }
  • prototype을 사용한 경우 ⇒ 하위 객체의 proto가 상위 객체를 링크하기 때문에 객체를 효율적으로 사용할 수 있다.
function Person(name) {
  this.name = name;
  Person.prototype.move = function () {
    console.log("이동합니다.");
  }
}

const p1 = new Person('gun');
const p2 = new Person('woo');
console.log(p1); // Person { name: 'gun' }
console.log(p2); // Person { name: 'woo' }
console.log(p1.__proto__); //{ move: [Function (anonymous)] }

Effective Prototype

상속을 흉내내기 - 1

부모 객체를 이용하여 프로토타입 함수 정의하기

function Person (name) {
  this.name = name;
}

Person.prototype.getName = function () {
  return this.name || "건우";
}

function Korean (name) {}

// 상위 객체의 함수가 링크됨 하지만 내부적으로 생성된 프로토타입 변수는 사용 불가
Korean.prototype = new Person(); 

const gun = new Person('gun');
const woo = new Korean('woo');

console.log(gun.getName()); // gun
console.log(woo.getName()); // 건우

상속을 흉내내기 - 2

부모 생성자를 빌려 쓰기

function Person (name) {
  this.name = name;
}

Person.prototype.getName = function () {
  return this.name || "건우";
}

function Korean (name) {
	// apply함수를 통해 Korean 생성자 함수에 전달된 인자들을 Person 생성자 함수에 적용시키는 역할을 함
  Person.apply(this, arguments);
}
Korean.prototype = new Person();

const gun = new Person('gun');
const woo = new Korean('woo');

console.log(gun.getName()); // gun
console.log(woo.getName()); // woo

Object.create

기존 객체를 재활용함

const woo = {
  name: 'woo',
  getName: function () {
    return this.name;
  },
};

const gun = Object.create(woo);
gun.name = "gun"

console.log(woo.getName()); // woo
console.log(gun.getName()); // gun
console.log(woo.__proto__); // [Object: null prototype] {}
console.log(gun.__proto__); // { name: 'woo', getName: [Function: getName] }

이벤트 루프

  • JS는 싱글 스레드로 call stack이 하나만 존재함 ⇒ 브라우저는 어떻게 비동기적으로 동작할까?
    • 브라우저에는 Multi Threaded로 event loop가 존재하여 비동기적으로 동작할 수 있음

브라우저의 비동기적 동작

  • JavaScript Runtime Environment에는 WebAPIs, Render, Microtask Queue, Task Queue
  • 브라우저는 Multi Threaded
  • Event Loop: Event Loop가 콜 스택과 테스크 큐를 반복해서 관찰하여 일을 처리하는데 콜 스택이 모두 비었을때 테스크 큐에 있는 함수 한 개를 콜 스택으로 옮김

JavaScript Runtime Environment

  • JS의 Runtime 환경은 WebAPIs, Render, Microtask Queue, Task Queue가 존재
  • WebAPIs
    • 브라우저에서 제공하는 API로 브라우저의 멀티쓰레딩을 이용할 수 있음 (ex setTimeout)
    • 사용자가 등록한 콜백함수를 원하는때 task Queue에 삽입
  • Task Queue
    • Web APIs에서 사용자가 등록한 콜백 함수를 특정한 이벤트가 발생했을때 테스크 큐에 삽입
  • Microtack Queue
    • 프로미스와 Mutation Observer API가 마이크로태스크 큐를 사용해 콜백을 호출
    • Event Loop는 task queue의 콜백 함수를 한 개씩만 콜 스택으로 이동시키지만 microtask queue에서는 큐가 모두 비어있는 상태가 될때까지 콜 스택으로 콜백함수를 이동시킴
  • Render: 주기적으로 브라우저에서 사용자가 요소들을 움직이거나 애니메이션 할때 화면에 업데이트를 함
    • Request Animation Frame이라는 API를 사용한 콜백은 Render의 가장 앞부분에 등록된다.
    • Requset Animation Frame은 브라우저에서 다음 랜더링이 발생하기 전에 해당 콜백이 수행되는 것을 보장

Microtask Queue와 Task Queue 차이점

  • Task Queue
    <body>
      <button>Click</button>
      <script>
        function handleClick(){
          console.log('handleClick');
          setTimeout(() => {
            console.log('setTimeout');
            handleClick();
          }, 0);
        }
        const button = document.querySelector('button');
        button.addEventListener('click', handleClick)
      </script>
    </body>
    
    //handleClick과 setTimeout이 계속해서 출력되고 버튼 클릭등이 계속 가능하다.
    setTimeout 호출 → 콜백함수 호출 → 태스크 큐에 삽입 → 콜 스택 이동 → 콜백 함수 수행 → setTimeout 호출 ..... 반복
  • Microtask Queue
    <body>
      <button>Click</button>
      <script>
        function handleClick(){
          console.log('handleClick');
          Promise.resolve(0)
            .then(() => {
              console.log('then');
              handleClick();
            })
        }
        const button = document.querySelector('button');
        button.addEventListener('click', handleClick)
      </script>
    </body>
    
    //handleClick과 setTimeout이 계속해서 출력되지만 버튼 클릭 등이 작동하지 않는다.
    버튼 클릭 → 콜백함수가 테스크 큐에 삽입 → 콜 스택으로 콜백 함수 이동 → 프로미스 생성 및 프로미스가 완료되었을때 프로미스 then이 마이크로 테스크 큐에 삽입 → 마이크로 테스크 큐에 있는 then을 콜스택으로 이동 →
    then 수행 및 또 다른 then을 마이크로 테스크 큐에 삽입 → 마이크로 테스크 큐에 들어온 새로운 then을 다시 콜 스택에 삽입(마이크로 테스크 큐가 모두 비어있는 상태가 될때까지 반복)

모듈

모듈을 사용할 시 스크립트간 의존도 파악이 가능하고 실행 순서를 쉽게 제어할 수 있다.

모듈과 컴포넌트의 차이

  • 모듈: 설계 시점에 의미있는 요소
  • 컴포넌트: 런타임 시점에 의미있는 요소

JS의 모듈

  • JS의 모듈은 직접적으로 런타임에 실행이 됨
    • 제대로된 모듈 역할을 하기 위해 디렉토리 단위를 모듈 개념에 가깝게 사용함
  • JS 모듈의 특징
    • 항상 use strict로 실행된다.
    • 모듈 레벨 스코프가 있음
      <body>
        <script type="module">
          let a = 5;
          let b = 10;
          const c = a+b;
        </script>
        <script type="moudle">
          alert(c); //오류 발생
        </script>
      </body>
    • 단 한번만 평가됨
      <body>
        <script type="module">
          import './hello.js'; // Hello, World 출력
        </script>
        <script type="moudle">
          import './hello.js'; // 한 번만 평가되기 때문에 출력되지 않음
        </script>
      </body>
    • 지연이 됨(defer를 적용한 것과 같다.)
      <body>
        <script type="module">
          console.log(text); // DOM 생성이 안된 상태, 아직 text가 정의되지 않음
        </script>
        <script type="moudle"> 
          console.log(text); // text 출력됨
        </script>
      	<p id="text">Hello, World</p>
      </body>

유니코드

CCS (Coded Caracter Set)

  • 문자들을 Code Point(정의해둔 정수값)에 대응시켜 만든 코드화된 문자들의 집합 ⇒ Code Point가 Character의 식별자 역할을 함

CES (Caracter Encoding Scheme)

  • CCS를 8bit 집합에 대응시키는 것
  • CES와 CCS는 1:1로 대응됨
  • 인코딩에 해당됨(UTF-8, euc-kr 등)

TES (Tranfer Encoding Syntax)

  • 인코딩된 문자가 특정 프로토콜을 타고 전송되도록 변환하는 것 ⇒ 통신 프로토콜에 제약이 있을 수 있어 사용함(ex. URL에서 공백은 사용할 수 없어 변환이 필요함)

유니코드

  • 전 세계 문자(이모티콘 포함)를 컴퓨터로 다룰 수 있도록 만든 표준 시스템
  • 다양한 나라가 서로 다른 인코딩 방식을 사용해서 호환성 및 확장성 문제를 해결하기 위해 탄생함
  • 유니코드에서 영어, 한글 모두 2바이트로 읽힘 ⇒ 한글은 한 글자당 길이 1을 차지함
  • 유니코드의 CCS: Code Point 범위(0x0 ~ 0x10FFFF, 1114112개 문자)
  • 유니코드의 CES: Code Point가 어떤 단위로 조합되어 인코딩되는 지 정의한 것

정규표현식

  • 정규표현식의 목적: 패턴을 이용하여 문자열에서 원하는 문자를 검색, 대체, 추출이 가능하다.
  • 성능은 느리지만 매우 편해서 짧은 문자열의 경우엔 많이 사용한다.
  • 정규표현식 테스트 페이지 Rubular

정규표현식 표현

/regexr/i ⇒ /: 시작, 종료 기호, regexr: 패턴, i: 플래그

예시1

  1. 휴대폰 번호 패턴 ⇒ 세 자리 숫자 + 하이픈, 셋 또는 네 자리 숫자 + 하이픈, 네 자리 숫자 패턴으로 이루어져 있음
  2. \d{3} = 세 자리 아무 숫자
    \d{3, 4} = 세, 네 자리 아무 숫자
    위의 패턴을 조합
  3. \d{3}-\d{3, 4}-\d{4}

예시2

  1. 이메일 주소 패턴 ⇒ 문자열, @, 문자열, ., 문자열 패턴으로 이루어져 있음
  2. .+ = 한개 이상의 문자열
    (…) = 캡처(그룹으로 묶어주기 때문에 중복 사용이 가능)
    이메일 패턴 = .+@.+..+
  3. 중간 문자열만 추출하려면?
    패턴 = .+@(.+)..+ ⇒ 캡처를 사용하자

정규표현식 연습 페이지

RegexOne - Learn Regular Expressions - Lesson 1: An Introduction, and the ABCs

Regex Golf

JS에서 정규표현식 사용하기

  • JS는 RegExp 객체로 정규표현식 기능을 제공함 (Array, Object 처럼 Literal로 생성 가능함)
    // 생성자 함수 방식
    const regExp1 = new RegExp("^\d+");
    const regExp2 = new RegExp("^\d+", "gi");
    
    // 리터럴 방식
    const regExp3 = /^\d+/;
    const regExp4 = /^\d+/gi;

정규표현식 객체 함수

  • test 함수: 입력받은 문자열에 찾는 패턴이 있는지 찾은 후 있다면 true 반환
    const msg1 = "안녕하세요 제 전화번호는 010-8741-4496입니다.";
    const msg2 = "아직 전화번호가 없어요..."
    
    const regExp1 = /\d{3}-\d{3,4}-\d{4}/;
    const regExp2 = new RegExp("\\d{3}-\\d{3,4}-\\d{4}");
    
    console.log(regExp1.test(msg1)); // true
    console.log(regExp1.test(msg2)); // false
    
    console.log(regExp2.test(msg1)); // true
    console.log(regExp2.test(msg2)); // false
  • exec: 입력받은 문자열에 찾는 패턴이 있는지 찾은 후 일치한 패턴 정보를 반환하고 없으면 null을 반환(문자 추출)
    const msg1 = "안녕하세요 제 전화번호는 010-8741-4496입니다.";
    const msg2 = "아직 전화번호가 없어요..."
    
    const regExp1 = /\d{3}-\d{3,4}-\d{4}/;
    const regExp2 = new RegExp("\\d{3}-\\d{3,4}-\\d{4}");
    
    console.log(regExp1.exec(msg1));
    console.log(regExp1.exec(msg2));
    
    console.log(regExp2.exec(msg1));
    console.log(regExp2.exec(msg2));
    
    // 패턴이 존재하는 경우
    // [
    //   '010-8741-4496',
    //   index: 14,
    //   input: '안녕하세요 제 전화번호는 010-8741-4496입니다.',
    //   groups: undefined
    // ]
    
    // 패턴이 존재하지 않는 경우
    // null 반환

String 객체 함수

  • match: String 객체에서 사용할 수 있는 함수로 정규표현식 객체를 파라미터로 받아 패턴이 있는지 찾은 후 일치하는 패턴 정보를 반환(정규표현식 객체의 exec 함수와 같음)
    const msg1 = "안녕하세요 제 전화번호는 010-8741-4496입니다.";
    const msg2 = "아직 전화번호가 없어요..."
    
    const regExp1 = /\d{3}-\d{3,4}-\d{4}/;
    const regExp2 = new RegExp("\\d{3}-\\d{3,4}-\\d{4}");
    
    console.log(msg1.match(regExp2));
    console.log(msg2.match(regExp1));
    // 출력결과는 exec 함수와 동일
    • 캡처가 적용된 정규표현식을 이용하면 match 반환값의 1번 인덱스부터 순차적으로 캡처 결과가 들어간다.
      const msg2 = "010-1234-5677말고 010-2222-2222로 전환주세요."
      
      const regExp1 = /(\d{3})-(\d{3,4})-(\d{4})/; 
      
      console.log(msg2.match(regExp1));
      // [
      //   '010-1234-5677',
      //   '010',
      //   '1234',
      //   '5677',
      //   index: 0,
      //   input: '010-1234-5677말고 010-2222-2222로 전환주세요.',
      //   groups: undefined
      // ]
  • replace: 정규표현식 객체를 파라미터로 받아 패턴이 있는지 찾은 후 일치한 패턴 정보를 원하는 문자열로 바꿈(문자열 대체)
    const msg1 = "안녕하세요 제 전화번호는 010-8741-4496입니다.";
    const msg2 = "010-1234-5677말고 010-2222-2222로 전환주세요."
    
    const regExp1 = /\d{3}-\d{3,4}-\d{4}/g; // 옵션으로 g를 붙이면 패턴에 맞는 모든 문자열이 변경됨
    const regExp2 = new RegExp("\\d{3}-\\d{3,4}-\\d{4}");
    
    console.log(msg1.replace(regExp2, "전화번호")); // 안녕하세요 제 전화번호는 전화번호입니다.
    console.log(msg2.replace(regExp2, "전화번호")); // 전화번호말고 010-2222-2222로 전환주세요.
    console.log(msg2.replace(regExp1, "전화번호")); // 전화번호말고 전화번호로 전환주세요.
  • search: 정규표현식 객체를 파라미터로 받아 패턴이 있는지 확인 후, 일치한 패턴 정보의 위치를 반환(문자 검색)
    const msg1 = "안녕하세요 제 전화번호는 010-8741-4496입니다.";
    const msg2 = "010-1234-5677말고 010-2222-2222로 전환주세요."
    
    const regExp1 = /\d{3}-\d{3,4}-\d{4}/g; // 옵션으로 g를 붙이면 패턴에 맞는 모든 문자열이 변경됨
    const regExp2 = new RegExp("\\d{3}-\\d{3,4}-\\d{4}");
    
    console.log(msg1.search(regExp2)); // 14
    console.log(msg2.search(regExp1)); // 0, 옵션에 상관 없이 처음 매칭된 값을 반환함
  • 개미 수열
    • 수학적인 수열 중 하나로, 이전 항에서 반복되는 숫자들의 개수를 나타내는 수열
    • 개미 수열의 시작은 항상 1 이고 다음 항부터는 이전 항에서 반복되는 숫자들의 개수를 순서대로 기록함, 각 숫자의 개수는 해당 숫자를 연속해서 나타내는 횟수를 의미
      • 예시
      1. 1 ⇒ 시작은 1
      2. 11 ⇒ 첫 번째 항의 수 1은, 1개의 1
      3. 21 ⇒ 두 번째 항의 수 11은, 2개의 1
      4. 1211 ⇒ 세 번째 항의 수 21은, 1개의 2, 1개의 1
      5. 111221 ⇒ 네 번째 항의 수 1211은, 2개의 1, 1개의 2, 1개의 1
    • 정규표현식으로 풀어보기
      function getAntSeq(n) {
        let seq = '1';
      
        for (let i = 1; i < n; i++) {
          // \1*은 캡처된 문자와 동일한 문자들의 반복을 의미
          seq = seq.replace(/(.)\1*/g, match => match.length + match[0]);
        }
      
        return seq;
      }
      
      console.log(getAntSeq(5)); // 출력: 111221

쿠키와 세션, 웹 스토리지

HTTP 통신

  • HTTP Request는 기본적으로 상태가 존재하지 않음
  • 서버는 어떤 브라우저에서 요청이 온 것인지 알 수 없는데 이를 해결하기위해 헤더에 쿠키를 담아서 요청하면 서버가 어디서 요청이 온 것인지 알 수 있음

Cookie(쿠키)

  • 클라이언트에서 저장, 관리하는 데이터로 브라우저를 닫아도 데이터 유지가 가능함
  • 서버가 Set-Cookie를 응답 헤더로 내려주면 클라이언트는 받아서 저장
  • 클라리언트에서 자체적으로 조작 가능
  • 각 상태에 수명 설정 가능
  • 키와 값, 옵션을 가지고 있음
  • 응답 헤더에 담으면 브라우저가 알아서 저장
  • 옵션
    • Expires: 쿠키 만료 날짜 지정
    • Secure: HTTPS에서만 쿠기 전송
    • HttpOnly: JS에서 쿠키 접근을 막음 ⇒ XSS 공격을 막을 수 있음
    • Max-Age: 쿠키 수명을 설정(Expires 설정은 무시됨)
    • Domain: 도메인이 일치하는 요청만 쿠키를 전송
    • Path: 패스와 일치하는 요청만 쿠기를 전송

쿠키의 취약점

  • XSS(Cross-Site Script, JS를 사용해 다른 사용자의 쿠키 값을 탈취하는 것)공격을 당할 수 있음
    • HttpOnly로 막을 수 있지만 최근 SPA로 웹페이지를 제작하기 때문에 사용이 어려움
    • 쿠키를 암호화하지 않고 보낼 경우 쿠키값을 중간에 탈취 당할 수 있음 ⇒ HTTPS를 이용하여 해결함

Session(세션)

  • 쿠기에 HTTP Session ID를 식별자로 담아 보내면 해당 식별자로 서버는 사용자를 구분한
  • 클라리언트는 HTTP Session ID를 쿠키 형태로 저장
  • 서버 자체적으로 기록하고 관리

세션의 문제점

  • 세션은 서버에 파일로 저장되기 때문에 사용자가 많은 경우 저장 공간에 한계가 생긴다
  • 서버가 2대일 경우 세션 관리가 어려움

⇒ 이러한 문제를 해결하기위해 서버와 클라이언트 간의 인증은 JWT같은 별도 토큰을 이용하고 쿠키관리 는 클라이언트 자체적으로 지속적인 데이터 관리 용도로 많이 사용함

웹 스토리지

  • 클라이언트에 데이터를 저장하기 위해 쿠키 대신 등장한 새로운 방법
  • HTML5부터 등장
  • 쿠키에서 하기 힘든 것들을 지원함
  • 로컬 스토리지와 세션 스토리지가 있음
    • 로컬 스토리지
      • 로컬 스토리지에 저장된 데이터는 반영구적으로 데이터가 저장됨
      • 브라우저를 종료해도 데이터가 남음
      • 저장했던 도메인과 이용하는 도메인이 다른 경우엔 접근할 수 없음
      • Key와 Value 형태로 저장
    • 세션 스토리지
      • 새 창을 생성할 때마다 개별적으로 저장되는 데이터
      • 브라우저를 닫는 순간 사라짐
      • 같은 도메인이어도 세션이 다르면 데이터에 접근할 수 없음
      • Key와 Value 형태로 저장

Indexed DB

  • Transactional한 로컬 데이터베이스로 새로운 웹 브라우저 표준 인터페이스
  • 브라우저에서 데이터를 영구적으로 저장하고 검색하기 위한 웹 스토리지 기술 ⇒ 클라이언트 측에 대량의 구조화된 데이터를 저장할 수 있는 고급 웹 스토리지 솔루션
  • RDB와 유사한 개념을 가지고 있으며 Key와 Value 형태로 저장
  • JS API를 통해 사용되며 웹 애플리케이션에서 데이터를 영구적으로 저장하고 쿼리가 가능
  • 객체 스토어(Object Store)라는 개념을 사용하여 데이터를 저장, 객체 스토어는 테이블과 비슷한 개념으로 이해으로 각 객체 스토어에는 Key-Value 쌍이 저장
  • 데이터 검색을 위한 인덱스를 지원
  • 비동기 작업이 가능
profile
컴퓨터공학과 학생입니다

0개의 댓글