6. ft_transcandence

zinnnn37·2024년 1월 22일
0

🪐 42 SEOUL

목록 보기
10/10

1. SPA(Single Page Application)

1.1. SPA vs MPA

📌 브라우저 내부에서 동작하는 앱: 사용하는 동안 페이지를 전환하지 않음
📌 웹 사이트의 페이지를 동적으로 바꿔가며 표현하는 것
→ 이벤트가 발생하거나 url이 변경되는 경우 브라우저 내부의 일부 리소스만 변경됨
📌 e.g. Gmail, Google Maps etc.

  • PROS
    • 필요한 리소스만 부분적으로 로딩한다. 전체 페이지를 업데이트 할 필요가 없어 속도가 빠르고 새로고침이 발생하지 않는다.
    • 서버의 템플릿 연산을 클라이언트로 분산 가능하다.
    • 모바일 앱 개발 시 동일한 API를 사용하도록 설계 가능하다.
  • CONS
    • JavaScript 파일을 한 번에 받기 때문에 초기 구동속도가 느리다.
    • JavaScript가 필요하다. 사용자가 자신의 브라우저에서 JS를 비활성화하는 경우 정상적으로 동작하지 않는다.
    • 검색 엔진 최적화(SEO)에 어려움이 있다.
    • CSR 방식을 사용하는 경우 클라이언트 측 쿠키 외에 사용자에 대한 정보를 저장할 공간이 마땅치 않다.
      → 클라이언트에 스크립트 코드를 삽입하여 개발자가 고려하지 않은 기능이 작동하게 할 수 있음(XSS: Cross-Site Scripting)

vs MPA(Multiple Page Application)

  • 사용자가 새로운 url 요청하는 경우 그 url에 해당하는 리소스를 서버에 요청, 서버의 응답을 통해 페이지를 렌더링하는 방식(전통적인 방식)
  • 페이지의 전체 리소스를 요청하므로 새로고침이 발생

    + 검색 엔진 최적화를 하기 적절하고 쉽다.
    + 최초 페이지 로딩이 빠르다(서버에서 렌더링하여 가져오기 때문)
    - 매 페이지 요청마다 새로고침이 발생한다.
    - 페이지 이동 시 중복된(불필요한) 리소스도 로딩된다.
    - 모바일 앱 개발 시 추가적인 백엔드 작업이 필요하여 개발이 복잡해질 수 있다.

SSR vs CSR

📌 SSR(Server Side Rendering)
: 모든 템플릿은 서버 연산을 통해 렌더링하고 완성된 페이지 형태로 응답한다.
: MPA에서 주로 사용한다.

  • PROS
    • SEO에 특화: 브라우저에서 JS 코드가 동작하기 전에도 완성된 형태의 템플릿(HTML에 데이터가 삽입된 상태)을 서버로부터 전달받아 검색로봇이 페이지를 크롤링하기 적합하다.
    • XXS가 잘 발생하지 않는다.

📌 CSR(Client Side Rendering)
: 최초에 한 번 서버에서 전체 페이지를 로딩, 이후 사용자의 요청이 올 때마다 리소스를 서버에서 제공하면 클라이언트가 해석하고 렌더링하는 방식이다.

XXS

  1. Reflected XXS
    : url 파라미터에 ㅅ크립트 코드를 넣어 서버를 거치지 않고 스크립트를 생성하는 방식
    : 일반적으로 브라우저 자체에서 차단되는 경우가 많다.

  2. Stored XXS
    : 사이트 내 게시글의 댓글, 닉네임 등에 스크립트 코드를 작성하여 서버에 저장함으로써 해당 게시글을 열람한 사용자를 공격하는 방식

📌 쿠키 정보, 세션 ID 등을 획득할 수 있는 스크립트 코드를 작동시킴으로서 공격자는 특정 사용자의 쿠키, 세션 ID를 획득할 수 있다. 이를 통해 공격자는 정상 사용자처럼 사이트에서 활동할 수도 있다.
📌 시스템을 통제할 수 있는 악성 데이터를 스크립트 코드에 포함시킴으로써 사용자의 시스템을 통제할 수 있다.
📌 악성코드를 다운로드하는 url로 사용자를 리다이렉트 시킬 수 있다.
📌 거짓 페이지를 노출시킬 수 있다. <img> 태그를 사용해 원래 페이지와 전혀 관련 없는 페이지를 표시할 수 있으며 이를 통한 개인정보 유출의 위험이 있다.

스크립트 코드에 대한 문자열을 필터링하는 방식으로 방지 가능

  • XXS 방지
  1. 필터 제작
    : XXS를 유발하는 스크립트 코드 input을 문자열로 받아들일 수 있도록 모든 특수문자를 이용해 HTML 엔티티로 필터링한다(replace()). HTML Entities

  2. BBCode 사용
    : 만들기 편하고 안정성도 높은 편이다. BBCode

  3. 쿠키 보안 옵션
    : 쿠키 생성 시 보안쿠키 파라미터를 지정하면 TLS(Transport Layer Security, 전승 계층 보안) 상에서만 사용 가능하다.

  4. 콘텐츠 보안 정책(CSP) 사용
    : 스크립트 실행 정책을 설정하여 예방하는 방법으로 출처가 자기 서버인 스크립트만 실행될 수 있도록 한다.

  • Routing
    - Routing: 어떤 네트워크 내에서 통신 데이터를 보낼 최적의 경로를 선택하는 과정
    - Router: 네트워크 상에서 데이터 패킷을 전송하는 네트워크 장치
    - Page Routing: 요청한 경로에 맞는 페이지를 선택하고 반환하여 사용자가 그 페이지에 접속할 수 있도록 하는 과정

2. VanillaJS로 SPA 구현

  • index.html이 유일한 html 파일, 최초 진입점

📌 History API 사용
📌 pushState() 메소드로 url을 History 객체에 넣고 url에 해당하는 리소스로 화면 렌더링
📌 PATH로 바로 접근하려면 배열보다는 객체

const routes = {
  "/": Home,
  "/about": About,
};
// 객체 안에 객체 넣어도 될 듯?
  1. 라우트 배열 생성
  2. pushState() 메소드를 이용해 url 변경
    → 적절한 이벤트리스너를 사용하여 url 변경 시 라우트 배열에서 컴포넌트를 찾아 렌더링하는 함수 호출
  3. 뒤로가기의 경우 popstate 이벤트 이용
// App.js
...
const routes = [
    { path: '/', view: homePage, title: 'Home' },
    { path: '/settings', view: settings, title: 'Settings' },
  ];

this.render = () => {
  const results = routes.map((route) => {
    return {
      route,
      result: location.pathname.match(pathToRegex(route.path))
    };
  });

  let match = results.find((route) => route.result !== null);
    
  };

...

📌 우리 팀은 class로 구현

// 기본적인 componet 틀
export default class Component {
  $target;
  props;
  state;

  constructor($target, props) {
    this.$target = $target;
    this.props = props;
    this.setup();
  }

  setup() {
    this.setEvent();
    this.render();
  }

  mounted() {}

  template() {
    return ``;
  }

  render() {
    this.$target.innerHTML = this.template();
    this.mounted();
  }

  setEvent() {}

  addEvent(eventType, selector, callback) {
    const children = [...this.$target.querySelectorAll(selector)];
    this.$target.addEventListener(eventType, (event) => {
      if (!event.target.closest(selector)) return false;
      event.stopImmediatePropagation();
      callback(event);
    });
  }
}

🌱 setup: 필요한 변수 설정, 소켓 연결 등
🌱 setEvent: 이벤트 리스너 관련 설정
🌱 render: 페이지 렌더링
🌱 template: 페이지 기본 틀 생성
🌱 mounted: template를 기준으로 각종 컴포넌트 생성
🌱 addEvent: 이벤트 리스너 추가

⚠️ 컴포넌트 생성 시 생성자만 호출하면 된다 ⚠️
변수에 할당 시 [object Object]가 화면에 출력되는 이슈가 있음! router 구현 다 했는데 이거 때문에 며칠동안 고생함..


Reference

XXS 1
XXS 2
VanillaJS로 SPA 구현 1
VanillaJS로 SPA 구현 2
VanillaJS로 SPA 구현 (1+2)
VanillaJS로 SPA 구현 3

0개의 댓글