웹 입문자라면 알아야되는 기본 지식들

인트로

요즘 많은 분들이 웹 개발에 입문하고 계십니다.
어떤 분은 프론트엔드 개발자를 희망하시고, 어떤 분은 백엔드 개발자를 희망하십니다.
혹은 둘 다 다루는 개발자가 되려는 분들도 계실겁니다.
어떤 개발자가 되건간에 웹 개발을 하려면 알아야되는 기초적인 지식이 있습니다.
이것을 간단하게 훑어보도록 합시다.

웹을 알기 전에

우선 웹이 무엇인지 알기 전에 좀 더 기반이 되는 지식을 알아두는 것이 좋습니다.
그래야만 웹을 좀 더 제대로 이해할 수 있습니다.

네트워크란

네트워크통신망이라고도 불리며, 컴퓨터들끼리 서로 통신할 수 있도록 연결돼있는 것을 말합니다. 통신이란 데이터를 주고받는 행위를 말합니다.

여러분이 사용하고있는 인터넷도 네트워크입니다. 인터넷은 전 세계의 컴퓨터들이 서로 통신할 수 있도록 연결되어 있는 것입니다. ISP(Internet Service Provider)라는 업체(KT, SKT, LG U+ 등)가 우리를 인터넷에 접속하게 해줍니다.

만일 여러분이 공유기를 사용하고 있다면, 이 공유기에 연결된 기기들 끼리도 네트워크가 형성됩니다. 이를 보통 사설 네트워크라고 부릅니다.

그림1 - 네트워크

그림1 - 네트워크
공유기를 쓰고 있다면 이렇게 컴퓨터들은 공유기를 통해 연결되어 있습니다.
그리고 공유기가 인터넷에 연결되어 있습니다.

기기들끼리 서로 통신하기 위해선, 서로를 특정지을 수 있는 무언가가 필요할겁니다.
어떤 컴퓨터가 어떤 컴퓨터와 통신을 해야하는데, 그게 어떤 컴퓨터인지 지칭할 수 없다면 통신할 수 없을겁니다.
그 지칭해줄 수 있는 걸 IP Address라고 합니다.
IP Address는 어떤 네트워크에서 컴퓨터에게 부여된 주소입니다.
서로 구분하기 위한 주소이므로 중복되지 않습니다. 즉 같은 네트워크 내에서 내 컴퓨터와 같은 IP Address를 가진 컴퓨터는 없습니다.

밑에서부턴 IP AddressIP라고 부르겠습니다.

그림2 - 공유기와 IP

그림2 - 공유기와 IP
그림에서의 예시처럼 공유기를 통해 형성된 네트워크 내에서 서로를 구분할 수 있는 주소(IP)가 부여됩니다.

앞서 IP는 중복되지 않는다고 했습니다. 하지만 같은 네트워크 내에서만 중복되지 않는다고 했습니다.
따라서 내 공유기에 연결된 컴퓨터에 192.168.0.100이라는 IP를 가진 컴퓨터가 있다 하더라도, 친구 집 공유기에 연결된 컴퓨터 역시 192.168.0.100이라는 IP를 가질 수 있습니다.
그 공유기에 연결된 기기 끼리만 서로 구분하는 IP이기 때문입니다.

그럼 여기에서 알 수 있는 사실이 하나 있습니다.
공유기를 통해 연결된 사설 네트워크에서 부여받은 IP로는 인터넷에 있는 다른 컴퓨터와 통신할 수 없다는겁니다.

그림3 - 공유기와 IP와 인터넷

그림3 - 공유기와 IP와 인터넷
공유기가 인터넷에 연결된 모습입니다.

위 그림을 보면 공유기에 IP가 할당되었습니다.
이 공유기에 할당된IP는 인터넷에서 부여받은 IP이므로 인터넷에 연결된 다른 기기와 중복될 수 없습니다.
즉 인터넷에서 서로 구분할 수 있는 주소이므로 이 IP를 통해 인터넷에 있는 다른 기기와 통신할 수 있는겁니다.

그럼 여기서 의문이 하나 들 수 있을겁니다.
인터넷 IP가 공유기에 할당돼있는데, 어떻게 인터넷에 연결된 다른 기기랑 공유기에 있는 특정 컴퓨터가 통신할 수 있는걸까요?
인터넷에 연결된 어떤 컴퓨터가 123.4.5.6이라는 IP로 데이터를 보내면 네 개의 컴퓨터 중에 어떤 컴퓨터에 전달되어야 할까요?
Port에 대해 알아보아야 합니다.

Loopback IP

루프백 IP란, 자기 자신을 가리키는 IP를 말합니다.
127.0.0.1이 대표적 예인데, 이 IP로 통신을 하려고 하면 자기 자신과 통신하게 되는 것입니다.

Port와 Port forwarding

Port에는 항구라는 뜻이 있지요. 컴퓨터를 하나의 땅덩어리로 본다면, 컴퓨터에는 여러 항구가 있습니다.

우선 공유기 없이 인터넷에 연결된 상황을 가정해보겠습니다.

그림4 - 공유기 없이 인터넷에 연결된 컴퓨터

그림4 - 공유기 없이 인터넷에 연결된 컴퓨터
공유기를 통하지 않고, 직접 인터넷에 연결되어 123.4.5.6이라는 IP를 부여받은 모습입니다.

이제 123.4.5.6이라는 IP로 데이터를 보내면 특정한 컴퓨터가 데이터를 받을 수 있을겁니다
그런데, 문제가 하나 더 있습니다.

이 컴퓨터에는 여러 프로그램이 실행중일 수 있습니다.
그리고 각각의 프로그램들은 네트워크 통신을 필요로 할 수 있습니다.
그런데 인터넷에서 보내온 데이터를 어떤 프로그램이 받아야 할까요? 어떤 프로그램에게 보내는 데이터인지 어떻게 알 수 있을까요?
이 때 Port라는 개념이 필요합니다.

그림5 - 포트

그림5 - 포트

내 컴퓨터에는 0번부터 65535번 까지의 포트가 있습니다. 다른 컴퓨터가 내 컴퓨터(123.4.5.6)로 데이터를 보낼 때 0번 포트로 보낼 수 있고 1번 포트로 보낼수도 있습니다.
내 컴퓨터에 실행된 프로그램들은 각자 포트를 하나 정해서, 해당 포트로 온 데이터는 그 프로그램이 가져가게 되는 것입니다.

보통 123.4.5.6:3000 이런 IP:PORT 형식을 사용합니다. 이렇게 IP와 PORT를 :로 구분하여 한꺼번에 표현할 수 있습니다.

이제 다시 공유기를 사용하는 상황으로 넘어와서 이야기 해봅시다.
그림6 - 공유기와 포트

그림6 - 공유기와 포트
A와 C 컴퓨터에서 각각 3000번 포트를 사용 중인 예시입니다.

만일 이 그림과 같은 상황에서 E 컴퓨터가 123.4.5.6:3000으로 데이터를 보내면 AC 중에 어떤 컴퓨터가 받아보아야 할까요?
이것을 해결해주는게 포트포워딩(port forwarding)입니다.

포트포워딩을 간단하게만 말씀드리자면 이렇습니다:

공유기로 통신이 들어왔을 때, 어떤 포트로 들어오면 어떤 컴퓨터로 데이터를 보낼지 정하는 것입니다.
가령 공유기에 3000번 포트로 온 통신은 192.168.0.100이라는 IP를 가진 컴퓨터의 3000번 포트에 전달하도록 하는 것입니다.
그렇게 하면 A 컴퓨터의 3000번 포트를 사용중인 프로그램이 데이터를 받아볼 수 있습니다.

그럼 C 컴퓨터의 프로그램도 데이터를 받아보게 하려면 어떻게 해야할까요?
예를 들어 공유기에 3001번으로 온 통신은 192.168.0.102라는 IP를 가진 컴퓨터의 3000번 포트에 전달하도록 하는 것입니다.
그렇게 하면 인터넷에 연결된 E 컴퓨터가 123.4.5.6:3001로 데이터를 보내서 C 컴퓨터가 받아볼 수 있는 것입니다.

서버와 클라이언트

여러분은 예를 들어 네이버, 다음, 구글 같은 사이트를 이용하거나 온라인 게임을 할 것입니다.

이런 서비스들은 인터넷을 통해 데이터가 오고 갑니다.
예를 들어 검색을 한다면 내 컴퓨터에 없는 데이터를 인터넷을 통해 가져오는 것입니다.

그럼 그런 데이터를 제공하는 무언가가 필요하겠지요? 그게 서버입니다.

그리고 네이버를 이용하려고 한다면, 크롬 같은 웹 브라우저로 탐색을 합니다.
크롬, 파이어폭스 같은 프로그램들을 웹을 탐색한다 해서 웹 브라우저라고 합니다.

이렇게 네이버에 데이터를 요청하고 받아오는 프로그램인 웹 브라우저는 클라이언트라고 합니다.
또, 온라인 게임을 하기 위해 우리 컴퓨터에 설치된 프로그램 역시 클라이언트입니다.

클라이언트는 무언가 요청을 하는 프로그램이고, 그 요청을 받아서 처리한 뒤 응답을 해주는 프로그램을 서버라고 합니다.

그림7 - 서버와 클라이언트

그림7 - 서버와 클라이언트
무언가 요청하는 프로그램은 클라이언트, 그 요청에 응답하는 프로그램은 서버입니다.

그리고 우리는 24시간 내내 언제든 네이버에 접속할 수 있습니다.
그 말은 네이버의 서버는 24시간 내내 구동중이라는 뜻이고, 네이버에서는 컴퓨터를 계속 켜 놓은 채로 있다는 것입니다.

HTTP란

통신을 하기 위해 정해진 규약들이 있습니다. 그 중 하나가 HTTP(Hyper Text Transfer Protocol)입니다.

데이터를 아무렇게나 보내면 상대 컴퓨터가 그것을 해석 못 하겠지요?
예를 들어서 'index.html이라는 파일을 달라'고 하고싶다면
어떤 사람은 'index.html'이라는 데이터를 보내고 싶을수도 있고
어떤 사람은 'GET index.html'이라는 데이터를 보내고 싶을수도 있고
어떤 사람은 'I want to get index.html'이라는 데이터를 보내고 싶을수도 있습니다.

그래서 '이런 식으로 보내라' 하고 약속한게 통신 규약입니다.
웹을 서비스하기 위해 사용되는 통신규약이 HTTP인 것입니다.

HTTP Message

HTTP에서, HTTP Message라는 방식을 통해 데이터를 주고 받습니다.
HTTP 메시지는 시작 줄, 헤더, 빈 줄, 본문으로 구성됩니다.

다만, 웹 개발 시 이 메시지를 직접 작성할 일은 웬만해선 없을겁니다.
웹 브라우저에서는 자동으로 만들어서 보내주며,
서버를 개발한다 하더라도 Express 같은 것을 이용하게 될텐데, 알아서 만들어서 보내줍니다.
다만 메시지가 어떻게 구성 되어 있는지를 알아 두어야 요청과 응답을 어떻게 해야 하는지 알 수 있을겁니다.

예를 들어 요청 메시지는 이런 식으로 구성되어 있습니다.

1
2
3
4
5
6
POST /login HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Content-Length: 24

{"id":"james","pw":"js"}

맨 첫 번째 줄인 POST /login HTTP/1.1은 어떤 요청을 하는지에 대한 정보이고
두 번째 줄 부터 빈 줄 바로 전 까지는 설명에 해당하는 헤더이고
빈 줄 다음부터는 본문(body)에 해당하는 내용입니다.


요청은

  • GET, POST, DELETE, PATCH, PUT 등과 같은 메소드
  • 어떤 리소스에 대한 요청인지 알 수 있는 URL
  • HTTP 버전 (이 부분은 그다지 신경 안 써도 됩니다)

으로 이루어집니다.

메소드는 서버가 수행해야할 동작을 나타냅니다.
웹 브라우저에 주소를 입력하여 서버에 요청하게 되면 GET 메소드로 요청하게 됩니다.

두 번째 부분인 URL의 구조를 우선 이해해야할 필요가 있습니다.

그림8 - url

그림8 - url

이런 식의 URL이 있다고 한다면

  • https:// 부분은 schem으로, 프로토콜 즉 어떤 통신 규약인지를 나타내고
  • www.naver.com 부분은 host로, 도메인 이름 혹은 IP
  • :8080 부분은 포트(port)
  • /hello/world 부분은 경로(path)
  • q=asdf&t=qwer 부분은 쿼리(query) (경로와 '?' 문자로 구분됨)

    통상적으로 쿼리 스트링(query string), 혹은 쿼리 파라미터(query parameter)라고 명칭합니다.

  • #result 부분, 즉 #부터 그 이후는 fragment입니다.

schem, host, port를 통해 서버를 찾아갈 수 있을겁니다.
그리고 path, query를 통해 서버가 정확히 어떤걸 요청하는지 알 수 있을겁니다.
fragment는 HTTP Message에 포함되지 않습니다. 즉 서버에 요청이 가는 내용이 아닙니다.

위 예시에서 http가 아닌 https라고 적었는데, 이건 나중에 다룰 기회가 되면 그 때 다루도록 하겠습니다.
포트 번호는 http일 경우 80번 포트, https일 경우 443 포트가 기본이기 때문에,
각각의 경우엔 포트 번호가 생략 됩니다.
http://www.naver.com:80http://www.naver.com이라고 포트 번호가 생략 됩니다.

그런데 예시로 보여드린 요청 메시지에서는 schem, host, port 등이 다 생략 돼있습니다.

  • fragment는 앞서 말씀드렸다시피 원래 메시지에 포함되지 않고,
  • query는 필요 없을 경우 꼭 적을 필요가 없습니다.
  • schem, host, port는 웹 브라우저 주소창에 입력하는게 아니라 사이트 내에서 같은 사이트로 요청할 경우 생략될 수 있습니다.

헤더는 설명입니다.
본문이 포함돼있는지, 본문은 길이가 얼마나 되는지, 어디서 요청했는지 등 여러 정보를 넣을 수 있습니다.


본문은 요청과 헤더에 들어갈 내용이 아니면서 추가적인 정보를 보내주어야 할 때 적어줍니다.
방문 기록이 그대로 남기 때문에, 만일 주소에 아이디와 비밀번호를 포함해서 로그인 하도록 구현한다면 다른 사람이 방문 기록을 보고 내 아이디로 로그인 할 수 있을겁니다.
그러므로 본문에 포함해서 보내주도록 합니다.

또, URL은 글자 수 제한이 있습니다.
게시글을 등록하도록 할 때에도 게시글의 내용은 본문에 포함시키도록 합니다.


메소드

이렇게 본문을 포함하여 무언가 '게시'하는 행동을 할 때에는 보통 POST 메소드로 요청하도록 합니다.

무엇인가 정보를 가져오기만 하는 요청은 보통 GET 메소드를 사용합니다.

그리고 GET 메소드의 요청은 본문을 포함하지 않습니다.

다만 보통 그렇게 한다는 것이지, 서버가 다르게 구현돼있으면 서버가 구현한대로 요청해야 합니다.
로그인인데 GET 메소드로 요청하게 서버가 구현되어 있다면 로그인이더라도 GET 메소드로 요청해야 합니다. 별로 좋은 생각은 아닌 것 같지만요.

응답 메시지

요청 메시지에 대한 예제만 봤으니, 응답 메시지의 예시도 한 번 간단하게 보여드리겠습니다.

1
2
3
4
5
6
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
Content-Length: 15

{"result":true}
  • HTTP/1.1은 HTTP 버전을 나타냅니다.
  • 200상태 코드입니다. 요청을 처리한 결과에 대해 알려주는 코드입니다.
    상태 코드는 이미 약속되어 있는 코드이므로, 서버는 상황에 맞게 응답해주면 됩니다.
  • OK상태 텍스트로, 간결하게 상태에 대해 사람들이 이해할 수 있도록 적어놓는겁니다.
  • 헤더는 위와 같습니다.
  • 클라이언트가 요청한 것에 대한 본문입니다. 본문이 항상 들어가지는 않습니다.

웹은 월드 와이드 웹(WWW, World Wide Web)을 간단히 줄여 부르는 말입니다.
웹이란 텍스트, 영상, 소리 등을 하이퍼 텍스트 방식으로 연결하여 제공해주는 서비스입니다.

하이퍼 텍스트란 어떤 문서에 다른 문서와 연결될 수 있는 것을 말합니다.
이렇게 연결되는 것을 하이퍼 링크라고 부릅니다.

웹 브라우저

을 탐색하게 해주는 프로그램으로, 주소창에 주소를 입력하여 원하는 웹 사이트에 접속하게 해줍니다.

을 제공해주는 서버는 웹 서버라고 불리며, 요청에 따라 알맞은 응답을 해줍니다.
요청응답은 앞서 설명드린 HTTP Message의 형태로 이루어져 있습니다.

HTML, CSS, Javascript와 웹 브라우저 렌더링

여기에서 영상, 소리 등과 관련된 파일은 설명하지 않고 HTML, CSS, Javascript에 대해 이야기 하도록 하겠습니다.

렌더링이란 무엇인지, 어떤 과정을 거치는지 간략하게 알아보도록 하겠습니다.

웹 브라우저에서 주소창에 웹 페이지 주소를 입력하게 되면, 우선 HTML을 응답 받게 됩니다. 그리고 HTML에 연결된 CSS, Javascript를 통해 화면을 그리게 됩니다.
즉 웹 브라우저를 통해 화면이 보여지는 과정을 렌더링이라고 합니다.

HTMLHyper Text Markup Language의 약자로 마크업 언어의 일종입니다.
마크업 언어는 문서나 데이터의 구조를 정의하는 언어입니다.
이렇게 작성된 html 문서를 통해 DOM Tree라는 것을 구성하게 됩니다.

CSSCascading Style Sheet의 약자로, 마크업 언어로 작성된 문서의 스타일을 지정하는 언어입니다.
어느 부분의 글자 색은 어떻고, 글자 크기는 어떻고, 배경은 어떻고... 등을 지정하게 됩니다.
이렇게 작성된 css를 통해 CSSOM Tree라는 것을 구성하게 됩니다.

그리고 이렇게 만들어진 DOM TreeCSSOM Tree를 통해 Render Tree라는 것을 만듭니다.
CSS에서는 어떤 요소는 보이지 않게 처리할수도 있는데, Render Tree에는 보이지 않는 것들은 제외하고, 그려져야될 것들에 대한 정보가 담겨있습니다.
Render Tree를 통해 화면이 그려지게 됩니다.

가령

1
2
3
#something {
   display: none;
}

이러면 #something에 해당하는 요소는 Render Tree에서 제외됩니다.

이 때, Javascript에서는 DOM을 조작할 수 있습니다. 즉 DOM Tree에 영향을 줄 수 있고, 이는 곧 Render Tree에도 영향을 줄 수 있다는 뜻입니다.
이렇게 DOM을 조작함으로 인해 웹 페이지가 동적으로 움직일 수 있게 됩니다.

파일 직접 열기

간혹 'html 파일을 더블클릭해서 열었더니 CSS가 적용이 안 돼요' 같은 질문을 받아보게 됩니다.

URL에 대한 설명을 조금 더 드리도록 해야겠습니다.

CSSJavascriptHTML 내부에 작성될 수도 있고, 파일과 연결이 될 수도 있습니다.
파일로 연결이 되는 예시를 보겠습니다.

<html>
    <head>
        <title>예제</title>
        <link rel="stylesheet" href="/master.css">
        <script src="/index.js"></script>
    </head>

    <body>
        예제입니다
    </body>
</html>

예를 들어서 웹 브라우저에 https://example.com/index.html이라는 주소로 접속하여 위와 같은 응답을 받았다고 해보겠습니다.

<link rel="stylesheet" href="/master.css">/master.css 경로로 요청하여 받은 css 파일을 이 문서에 적용시키겠다는 의미이고,
<script src="/index.js"></script>/index.js 경로로 요청하여 받은 js 파일을 이 문서에 적용시키겠다는 의미입니다.

그러니까 서버에서는 index.html 외에도 master.css 및 index.js의 요청에 대한 응답도 하도록 만들어둬야 된다는 것입니다.

/master.css/index.js로 자동으로 다시 요청하게 되는데, 이미 https://example.com/index.html라는 주소로 접속해서 요청하는 것이기 때문에 https://example.com을 생략하게 된 것입니다.

그리고 이 것을 절대경로라고 부릅니다.

일부 생략되었지만, https://example.com/master.css를 요청하게 된 것입니다.

프로토콜만 생략도 가능합니다.
//example.com/master.css라고 적어두면 https://example.com/index.html에서 요청한 것이기 때문에, 똑같이 https 프로토콜로 요청하게 됩니다.

/master.css 절대경로https://example.com/index.html에서 path 부분인 /index.html 부분을 떼고 /master.css를 붙였다고 보시면 됩니다.

만약에 예시로 든 index.html 파일이 있는 경로가 C:\Users\gear\Desktop\index.html라고 해봅시다. 그리고 이 파일을 더블클릭하여 열었다고 한다면, 이건 어떤 서버에 요청한게 아닙니다.

따라서 크롬에선 file:///C:/Users/gear/Desktop/index.html이라는 주소를 확인할 수 있을겁니다.

이 경우 /master.cssfile:///C:/Users/gear/Desktop/index.html에서 path에 해당하는 부분을 떼서 붙인 곳으로 요청이 가게 될겁니다.

프로토콜로는 file://이 붙을테고, host쪽은 아마 /C: 정도가 되는 듯 합니다.
그러니까 file:///C:/master.css로 요청이 가게 될겁니다.
그런데 css 파일은 index.html 옆에, 그러니까 C:/Users/gear/Desktop/index.html 경로에 두었다면 당연히 웹 브라우저가 찾지 못하겠지요?

이 것이 웹 서버를 통하지 않고 파일을 직접 열었을 때 알아두어야 할 점 중 하나입니다.

상대경로

앞서 절대경로라는 표현을 썼는데, 그럼 다른 경로도 있다는 뜻이겠지요?
상대경로라는게 있습니다.
.현재 경로, ..상위 경로를 말합니다.

무슨 말이냐 하면...

/hello/world/james.index라는 경로가 있다고 한다면
/hello 경로 안의 world 경로 안의 index.html이라는 파일을 의미할겁니다.
이 때 /hello/world라는 경로가 현재 경로가 됩니다.
그리고 /hello 경로는 /hello/world 경로의 상위 경로가 됩니다.

이 경로에서 ./master.css로 요청하게 되면 /hello/world/master.css로 요청이 가게 되는 것입니다.

../master.css로 요청하게 되면 /hello/master.css로 요청이 가게 되는 것입니다.

이 것을 응용해서 ../../master.css로 요청하게 되면 /master.css로 요청이 가게 될겁니다.

웹 서버

앞서 웹 서버을 제공하는 서버라고 말씀드렸습니다.
웹 서버는 Apache HTTP ServerNGINX 같은 Web Server를 이용해 요청에 따라 파일을 응답하게 될 수 도 있습니다.

요청에 따라 응답이 만들어지도록 하기 위해선, 예를 들어 Express 같은 것을 이용하여 WAS(Web Application Server)를 만들어 구동해야 합니다.
그러니까 로그인 기능이나 게시글 등록 같은 것들을 하도록 하기 위해서 필요한게 WAS란 말입니다.
이런 기능들은 그냥 정해진 파일을 응답 해 주는 것 만으로는 할 수 없다는 걸 아실겁니다.

WAS는 각각의 메소드 및 경로에 따른 요청마다 어떤 응답을 해야할지 작성해주어야 합니다.

HTTP Message를 다시 잘 기억해보시기 바랍니다

예를들어 이런 식입니다:

1
2
3
GET 메소드로 '/' 경로로 요청이 오면 => 메인 화면을 보여준다
GET 메소드로 '/post' 경로로 요청이 오면 => 게시글 목록을 보여준다
POST 메소드로 '/post' 경로로 요청이 오면 => 게시글을 등록해준다

CSR & SSR

앞서 웹 브라우저에서 렌더링을 한다(화면을 그린다)고 하였습니다. 그리고 Javascript를 통해 화면을 조작할 수 있다고 했습니다.
이렇게 Javascript를 통해 조작된 화면을 보여주는 것이 CSR(Client Side Rendering)입니다.
여기에서의 렌더링은 앞서 말씀드린 웹 브라우저가 하는 렌더링이 아니라 DOM을 조작하여 보여지는 화면을 조작하는 것을 말합니다.

이 글을 보는 여러분 중에는 JSPPHP 같은 것들을 들어본 분들도 계실겁니다.
JSPSSR을 위한 템플릿이며, PHP는 웹 개발을 위한 언어인데 전통적인 방식은 SSR을 합니다.

SSR이 무엇인지 설명드리겠습니다.
SSRServer Side Rendering의 약자로, 서버측에서 렌더링한다는 뜻입니다.

DOM은 웹 브라우저에서 만들어지는 것이라고 했습니다. 따라서 서버에서 다룰 수 있는건 html으로 작성된 문서입니다. 즉 애초에 웹 브라우저가 받아볼 html 문서를 조작하는 것입니다.

SSRCSR을 모두 하는 페이지가 있다고 한다면 이렇게 될겁니다:

  1. 웹 브라우저가 페이지를 요청
  2. 서버에서 요청에 맞게 html 문서를 생성(SSR)
  3. 웹 브라우저가 DOM Tree, CSSOM Tree, Render Tree를 만들어서 렌더링(화면을 보여줌)
  4. Javascript로 DOM을 조작(CSR)

SSR은 다른 방식으로도 할 수 있겠지만, JSPPHP에서 하는 전통적인 SSR은 이런 방식입니다(PHP):

1
2
3
4
5
<html>
<?php
    echo "안녕하세요, ".$_GET['name'];
?>
</html>

<?php ?> 블럭 안의 내용은 서버에서 실행됩니다.
echo는 뒤의 내용을 출력시킵니다.
그러니까 이런 식입니다:

1
2
3
<html>
<?php echo "hello world" ?>
</html>

의 결과는

1
2
3
<html>
hello world
</html>

가 됩니다.

$_GET쿼리로 넘어온 값을 가져옵니다.
가령 /경로?name=james로 요청이 와서 처리하게 된다면,
$_GET['name']"james"라는 문자열을 얻을 수 있습니다.

php에서 문자열을 합치는건 "문자열"."문자열" 같은 식으로 합칠 수 있습니다.
"안녕"."하세요"는 "안녕하세요"가 됩니다.

만일 /test.php라는 경로가 위의 내용을 응답하도록 했다면,

GET /test.php?name=james HTTP/1.1
<헤더 생략>

이렇게 요청할 경우

1
2
3
4
5
6
HTTP/1.1 200 OK
<헤더 생략>

<html>
안녕하세요, james
</html>

같은 응답을 받아보게 되는 것입니다.

즉 웹 브라우저는 이런 html 문서를 가지고 화면을 그리게 됩니다.

1
2
3
<html>
안녕하세요, james
</html>

간혹 Javascript에서 받아온 값을 php 혹은 jsp에서 처리하려고 하는데 왜 안 되냐는 질문을 하시는 경우가 있는데, 이는 잘못된 접근임을 알 수 있습니다.
php의 부분은 이미 서버에서 처리되어 웹 브라우저에 넘어왔고,
Javascript로 적힌 부분은 웹 브라우저에서 동작하기 때문에 논리적으로 실행 시점이 맞지 않는 것입니다.

로컬 서버

로컬 서버란, 그냥 개발중인 컴퓨터에서 실행한 서버 프로그램을 말합니다.
Loopback IP(127.0.0.1)로 접근할 수 있습니다.
그리고 당연히 인터넷을 통해 부여받은 IP로 접근할수도 있을겁니다.
공유기를 사용중이라면 공유기를 통해 부여받은 IP로 접근할 수도 있습니다.

가령 192.168.0.100과 같은 IP 주소

앞서 URLhost 부분은 도메인 이름 혹은 IP라고 말씀드렸었습니다.
도메인이 없으면 IP를 통해 웹 서버에 페이지를 요청할 수 있습니다.
http://127.0.0.1:8080과 같은 식으로 말입니다.

(웹 서버가 8080 포트를 차지하도록 했다는 가정)

DNS

앞서 내가 개발한 서버를 IP로 접근할 수 있다는 것을 알 수 있었을겁니다.
그런데 네이버 같은 서비스를 보면 www.naver.com이라는 멋진 도메인으로 접속이 가능합니다.

어떻게 이 것이 가능할까요?
바로 DNS(Domain Name System) 덕분입니다.

DNS란 도메인 이름을 네트워크 주소로 변환해주거나 그 반대로 할 수 있도록 해주는 시스템입니다.
DNS는 여러 기관에서 운영하고 있습니다.

그래서 우린 가비아 같은 곳에서 도메인을 구입하여 내 서버의 IP를 연결지어줘야 합니다.
그렇게 하면 도메인을 통해 내가 만든 웹 서버에 접속할 수 있게 됩니다.

AJAX

앞서 Javascript를 통해 화면 갱신을 할 수 있으며, 그것이 CSR이라는 것을 알게 되었습니다.
그리고 Javascript로는 웹 브라우저 주소창에 주소를 입력하지 않더라도, 그리고 페이지 이동을 하지 않더라도 서버와 통신이 가능합니다.

이 것을 비동기적인 통신(비동기 통신)이라고 부릅니다.

Javascript로 페이지 이동을 하지 않고 서버와 통신하며, 동적인 화면을 만드는 기술이 AJAX입니다.

XMLHttpRequest 객체를 이용하거나, fetch API를 이용하거나, 혹은 라이브러리를 이용하여(axios, jQuery.ajax 등) 그렇게 할 수 있습니다.

SOP & CORS

간혹 비동기 통신을 시도하면서 문제를 겪는 경우가 있었을겁니다.
그래서 무슨 일인지 알아보려고 개발자도구를 열어보았다면 CORS라는 단어가 눈에 띄었을겁니다.

CORS는 많은 개발 입문자분들을 괴롭히는 녀석입니다.
하지만 CORS가 무엇인지 알면 해결 방법을 찾을 수 있습니다.

그 전에 우선 SOP가 무엇인지부터 이해해야 합니다.
웹 브라우저는 보안상의 이유로 SOP(Same Origin Policy, 동일 출처 정책)라는 정책을 갖고 있습니다.
이 정책은 Origin(출처)이 같지 않은 리소스와 상호작용 하지 못하게 하는 것인데, 같은 출처이려면 프로토콜, 호스트(host), 포트가 모두 같아야 합니다.

예를 들어서 GET 메소드로 https://example.com/user?id=james에 요청을 하면 james라는 유저의 정보를 가져온다고 가정해보겠습니다.

그리고 내 로컬서버(8080 포트)에서 비동기 통신을 통해 저 주소로 요청하게 되면 우리는 SOP에 의해 막히게 됩니다.
Javascript로 응답을 받아서 처리할 수 없는 것입니다.
로컬서버의 출처는 http://127.0.0.1:8080이고 요청한 리소스의 출처는 https://example.com이기 때문입니다.

이건 웹 브라우저가 막는겁니다.
따라서 사용하고있는 웹 브라우저가 SOP를 해제할 수 있는 옵션을 제공한다면 그 옵션을 통해 무사히 Javascript가 처리할 수 있게 됩니다.
하지만 그렇게 하려면 모든 사용자들에게 특정 브라우저로, 특정 옵션 설정을 건드리라는 설명을 해줘야 합니다. 매우 번거롭습니다.
그리고 웹 브라우저가 이런 정책을 갖고있는데에는 보안적인 이유가 있습니다.
따라서 번거로움을 감수할 수 있다 하더라도 그런 방식으로 하면 안 좋은겁니다.

그런데 몇 가지 규칙만 지키면 출처가 다르더라도 사용할 수 있습니다.
그게 CORS(Cross Origin Resource Sharing)입니다.

그렇다면 CORS를 지키려면 어떻게 해야할까요?
좋은 글들이 있어 링크 남깁니다:
CORS는 왜 이렇게 우리를 힘들게 하는걸까?
Cross Origin Resource Sharing - CORS

추신 : 이 것을 Proxy 서버를 통해 해결하려는 경우가 종종 보입니다.
하지만 Proxy 서버를 통해 해결하는 것이 유일한 해결책이 아니며,
그것에 좋은 선택인지 검토가 필요합니다.

특히 외부 API를 사용할 때 CORS 문제에 부딪힌다면, 보통 API Key를 요청 내용에 담았을 것입니다.
Javascript의 요청에서 API Key가 적혀있게 되면, 손쉽게 노출될 수 있습니다.
웹 브라우저에서 일어나는 일이기 때문입니다.
웹 브라우저는 많은 것을 보여줍니다.

또, 본인 혹은 팀원이 만든 서버라면 그 서버 개발자와 협업하여 CORS 규칙을 지키면 됩니다. 굳이 번거롭게 Proxy 서버를 다시 둘 필요가 없습니다.
또한 본인이 제어할 수 없는 Proxy 서버를 이용한다면, 외부 서비스에 너무 의존적이게 된다는 점에 주의해야 합니다.
그 것이 무조건 나쁘다고만은 할 수 없지만, 외부 서비스에 의존적이란 말은 외부 서비스에 문제가 생기면 내 서비스에도 문제가 생긴다는 뜻입니다.

하지만 React나 Vue 같은 도구를 이용해서 개발하시는 프론트엔드 개발자라면 주저없이 Proxy 서버 옵션을 사용하는 것이 좋은 선택일 것입니다.
왜냐하면 개발 중에 발생하는 CORS 문제는 내가 만든 것들이 로컬 서버에서 동작하고 있기 때문이지, 공개적으로 서비스 될 때에는 서버와 같은 출처로 제공될 수 있기 때문입니다.

상태 기억하기

앞서 웹 서비스가 어떻게 되는지 알아보았습니다.
웹 페이지를 요청하면 서버로부터 HTML, CSS, Javascript 등을 받아와 렌더링한다는 것이었습니다.

그렇다는건, Javascript를 통해 변경한 모든 것들이 페이지 이동을 하면 사라진다는걸 의미하기도 합니다.
왜냐면 모든걸 새로 받고 다시 처음부터 그리기 때문입니다.

그래서 페이지 이동을 하면서도 기억을 해야되는 내용이 있을 때 이용할 수 있는 몇 가지 수단이 존재합니다.

우선 정말로 기억해야되는 내용인지 충분히 검토하시기 바랍니다.

기억하는 방식이나 데이터 성격 등에 따라 방법을 달리 선택할 수 있습니다.

  • 쿼리
    쿼리는 URL에서의 쿼리를 말한겁니다. URL에 있으므로 1회성으로 기억해야될 때 이용할 수 있습니다. 기억한다기보단 그냥 그 페이지에서 유효한 값이 될겁니다.
  • 쿠키
    쿠키는 서버와 클라이언트가 계속 주고받는 쪽지 같은 것입니다.
    쿠키 옵션에 따라 Javascript에서 접근이 불가능한 쿠키도 있습니다.
    웹 브라우저에서 접근이 가능하므로 보안에 민감하지 않은 내용만 다루어야 합니다.
  • 세션
    세션은 서버에서 기억하는겁니다. 세션에 있는 내용은 웹 브라우저에 전달되지 않습니다.
    기억해두되, 보안상 정보가 공개되면 안 되는 부분은 세션에 기록해야 합니다.
  • 웹 스토리지(LocalStorage, SessionStorage)
    웹 브라우저에만 기록하는겁니다.
    로컬스토리지는 영구적으로 기록하고, 세션스토리지는 창을 닫으면 기록이 사라집니다.

웹 말고 다른 환경에서의 자바스크립트

웹 프론트엔드를 희망하거나 입문한 분들은 Node.js라는 것을 접하게 될겁니다.
이게 대체 뭐일까? 배워야하나? 현업에선 Node.js를 쓴다던데... 같은 생각이 들겁니다.

Node.js란

앞서 웹 브라우저에서는 HTML, CSS, 그리고 Javascript를 해석하여 다룬다는 내용을 말씀드렸습니다.
즉 웹 브라우저 위에서 Javascript로 작성된 소스코드가 동작한다는 것입니다.
웹 브라우저에서 Javascript가 동작하기 때문에 웹 브라우저는 자바스크립트 런타임 환경입니다.

그리고 Node.js 역시 자바스크립트 런타임 환경입니다.
Node.js도 자바스크립트를 동작시킬 수 있는 녀석입니다.

웹 브라우저는 웹을 탐색해야되기 때문에 Web API를 제공합니다.
이 글을 읽는 분이라면 접해보셨을 window.document, window.location 같은 것들이 Web API입니다.

Node.js는 웹 탐색이 목표가 아니라, CLI에서 자바스크립트를 구동하는 것이기 때문에 Web API가 제공되지 않습니다.
대신 웹 브라우저와는 다른 특별함이 있습니다.

CLI : Command Line Interface의 약자로, 명령 프롬프트 같은 프로그램 위에서 동작한다는 뜻입니다.

웹 브라우저는 여러 사이트를 안전하게 탐색하기 위해 SOP, CORS 같은 정책이 있습니다.
하지만 이건 웹 브라우저의 정책입니다. Node.js에는 없는 정책입니다.

또, 웹 브라우저에서는 보안상의 이유로 파일 접근하는것에 제한적입니다. Javascript로 사용자의 파일을 마음껏 뒤적거릴 수 없습니다.
input 요소를 통해 사용자가 직접 파일을 선택하도록 해야하고, 그렇게 선택한 파일을 Javascript로 변경하거나 삭제할 수 없습니다.
하지만 Node.js는 가능합니다. 물론 애초에 웹 화면을 보여주질 않으니 input 요소 자체가 있을 수 없지만요.

그래서 이런 Node.js를 통해서 할 수 있는 일 중에 대표적인 예가 웹 서버입니다.
Node.js는 웹 서버로 이용하기 위해 사용할 수 있습니다.
물론 대표적인 예이지 Node.js가 할 수 있는 유일한 일은 아닙니다.

그러면 React, Vue는 웹 서버가 아닌데 Node.js를 어떤 이유로 사용할까? 궁금하지 않으셨나요?
React와 Vue는 Webpack을 통해 분리된 js 파일들을 하나로 통합합니다.
그리고 변환됩니다.
React는 jsx라는 문법, Vue는 vue template을 사용하기 때문에 웹 브라우저에서는 이해할 수 없습니다.
웹 브라우저가 이해할 수 있는 방식으로 변환됩니다.(빌드)
또, Webpack은 로컬 서버를 실행해주어 바로바로 변경된 내용을 확인할 수 있도록 해줍니다.
만일 로컬 서버로 구동하지 않는다면 변경 내용을 확인할때마다 빌드를 해야 할겁니다.
이렇게 편한 WebpackNode.js 위에서 구동됩니다.

물론 Webpack만 있는건 아니고 다른 것을 쓸 수도 있지만 그것도 Node.js 위에서 돌아갑니다.

정리하며

이해하지 못한 부분이 있거나 좀 더 알아보고싶은 내용이 있으면 핵심이 되는 단어를 통해 검색을 해보세요. (기술적인 자료를 찾을땐 구글을 추천합니다)
아니면 책을 구매해보세요.

Edit
Pub: 16 Sep 2021 12:06 UTC
Edit: 17 Sep 2021 02:33 UTC
Views: 4917