SPA 구현하기 - history, hashbang

younoah·2021년 8월 23일
3

[My 자바스크립트]

목록 보기
12/17

SPA란?

SPA가 무엇인지 알려면, 기본적으로 웹이 어떻게 동작하는지 알아야 이해가 좋다.

hashbang과 history api를 이용하면 SPA를 구현할 수 있다.

다만 hashbang은 잘 사용하지 않고 주로 history api로 구현을 많이 한다.

일반적인 정적인 웹페이지

  • HTML 파일들로 페이지가 구성
  • url이 파일 경로와 이름이 된다.
  • url상 파일명이 없을경우 index.html을 찾으려함
  • 웹 서버에 정적인 파일을 업로드 해놓고 URL을 통해 사용자에게 제공하는 방식

웹 어플리케이션

  • 정적인 파일을 웹 서버로 제공하는 방식뿐만 아니라 PHP, JAVA, Python, Node.js 등을 이용해 서버에서 동적으로 HTML을 생성해서 제공하는 방식이다.
  • HTML을 서버에서 만들어서 내려주고, 이후 동작을 JS를 통해 하다보니 렌더링 시점이 뒤죽박죽 되는 문제가 있다.
  • 그러다보니 서버 렌더링 시점에서 구현했던 것을 클라이어튼에서 동적으로 렌더링 해야한다면 중복해서 구현이 필요하기도 하다.
  • UI를 생성하는 부분을 템프릸화해서 서버, 클라이언트에서 같이 쓸 수 있는 방안도 나오긴 했지만 환경에 따라 동작이 100% 일치하지 않는 문제가 발생하기도 했고, 궁긍적으로 유저 인터렉션 처리를 클라이언트 사이드에서 해야하기 때문에 모든 처리를 서버에서 할 수가 없다.
  • 이를 보완하기 위해 나온 개념이 SPA이다.

SPA

  • 이러한 흐름 소겡서, 서버는 API만 처리하고 아예 모든 렌더링을 클라이언트에서 하는 방시깅 대두되게 된다.
  • 이 경우 웹 애플리케이션에선 요청에 다른 데이터만 JSON 등으로 내려주고, 별도의 클라이언트 애플리케이션을 구성한다.
  • 클라이언트에선 HTML 파일인 index.html 하나만 존재하며 클라이언트에서 오는 모든 url 요청을 index.html로 돌린다.
  • 이후 동작은 url을 보고 어떤 페이지를 그릴지 동적으로 처리한다.
  • 이전 방식에서는 페이지를 이동할 때마다 페이지의 모든 내용을 새로 불러왔어야 했는데, SPA 내에선 렌더링만 다시 동적으로 하므로 처음 로딩 이후엔 네트워크 부담이 줄어드는 효과가 있다.
  • 대신 처음에 모든 파일을 전부 로딩하다 보니 처음에 시간이 오래걸리는 단점이 존재한다.

hashbang이란?

  • url 맨 뒤에 #을 이용해 처리하는 방식
  • #은 같은 페이지 내의 요소를 가리킬 때 많이 사용되었다.
http://localhost:5000/
http://localhost:5000/#list
http://localhost:5000/#qna

위의 url응 모두 같은 페이지(index.html)를 불러오며, 뒤에 붙은 #은 location.hash를 통해 가져올 수 있다.

  • 이 hash를 통해 어떤 페이지를 렌더링할지를 정하는 로직을 구현해서 쓰는 방식이다.

  • 해쉬 표기는 URL에서 항상 맨뒤에 있어야 된다.

http://localhost:5000/#list?id=1 // 이렇게 작성하면 안된다.
http://localhost:5000/?id=1#list // 이렇게 작성해야 한다.
http://localhost:5000/#list-1 // 혹은 이렇게 임시로 작성할 수도 있다.

location

window.location // 현재 윈도우의 url에서 해쉬를 가져온다.
location.search //  현재 윈도우의 url에서 쿼리스트링을 가져온다.

쿼리스트링 형태

?param1=value&param2=value...

hashbang으로 간단하게 spa를 구현할 수 있다.

hashbang은 url의 맨마지막에 위치해야하는 특성 때문에 일반적인 url사용방식과 다르고 이에 따라 쿼리스트링을 다루기 까다롭다.

히스토리 API를 지원하지 않는 옛날 브라우저에서 작동한다.

하지만 모던한 방식이 아니기때문에 hashbang이 아닌 history API 방식을 많이 사용한다.

history api

  • 브라우저에서 페이지 로딩을 하면, 세션 히스토리라는 것을 갖는다.

  • 세션 히스토리는 페이지를 이동할 때마다 쌓이게 되며, 이를 통해 뒤로가기 시 이전 페이지로 가거나 뒤로 간 이후 다시 앞으로 가는 등의 이동이 가능하다.

  • pushState, replaceState 두 개의 함수로 화면 이동 없이 현재 url을 업데이트 할 수 있다.

    • pushState: 세션 히스토리에 새 url 상태를 쌓는다.
    • replaceState: 세션 히스토리에 새 url 상태를 쌓지 않고, 현재 url을 대체한다.
  • hashbang의 hashchange 이벤트처럼, popstate 이벤트로 세션 히스토리의 변경을 감지할 수 있다.

    • popstate는 history.go(1) history.back(1) 를 감지한다.
  • 일반 url 형식을 따르기 때문에 쿼리스트링도 자유롭게 붙일수 있다.

    • /list?page=2&limit=10

문법

historay.pushState

history.pushState(state, title, url)
  • state: history.state에서 꺼내 쓸 수 있는 값이다.

  • title : 변경될 페이지의 title을 가리키는 값인 것 같지만 거의 대부분 브라우저에서 지원하지 않는다. null 혹은 빈 string을 넣으면 된다.

  • url : 세션 히스토리에 새로 넣을 url이다. (a태그를 클릭하거나 location.href로 url을 변경하는 것과는 다르게 이 url이 변경된다고 해서 화면이 리로드 되거나 하진 않는다.)

historay.replaceState

historay.replaceState(state, title, url)
  • state: history.state에서 꺼내 쓸 수 있는 값이다.

  • title : 변경될 페이지의 title을 가리키는 값인 것 같지만 거의 대부분 브라우저에서 지원하지 않는다. null 혹은 빈 string을 넣으면 된다.

  • url : 세션 히스토리에서 현재 url과 대체한 url이다. (a태그를 클릭하거나 location.href로 url을 변경하는 것과는 다르게 이 url이 변경된다고 해서 화면이 리로드 되거나 하진 않는다.)

history.state //
history.go(1) //
history.back(1) // 

history api를 사용할 경우, hashbang과는 다르게 a태그를 그대로 쓰면 의도한대로 동작하지 않느다.

왜내하면 a태그를 클릭했을 때 기본 동작은 href에 연결된 url로 이동을 해버리는데, history api에서 SPA처리를 하려면 이동을 하는게 아니라 바뀌는 요소만 다시 렌더링 해야하기 때문이다.

주의!

SPA는 어떤 url이던지 초기 페이지(index.html)에서 모든 url에 해당하는 페이지를 렌더링하는 방식이다.

따라서 경로가 있는 url에서 새로고침을 하거나 바로 접근하게 되면 페이지를 찾을수 없다는 404에러를 만나게 된다.

이는 실제로 해당 url에 html파일이 없기 때문이다.

예를들어 우리는 index.html 파일만 존재하는데 만약 localhost:5000/list 라는 url을 새로고침하거나 바로 접근하게 되면 404에러를 받는다.

이런것을 처리하기 위해서는 웹서버에서 만약 경로에 파일이 없다면 index.html을 띄우도록 설정을 해야한다.

profile
console.log(noah(🍕 , 🍺)); // true

0개의 댓글