본문 바로가기
Front-End/웹 (Web)

[HTTP/네트워크] HTTP와 브라우저 작동 원리

by MS_developer 2022. 10. 19.

 

 

처음 프론트엔드 개발에 대한 것을 배우고자 한다면 우선 가장 기본이 되는 HTML/CSS/JavaScript를 접하고 배우게 된다.

 

그리고 우리는 이 과정을 통해 웹 페이지의 뼈대가 HTML을 기반으로 한 하이퍼텍스트로 구성되어 있다는 것을 알 수 있었다.

 

이전 포스팅에서 언급 했듯, 웹 브라우저는 HTML과 같은 문서를 전송하기 위해 HTTP(HyperText Transfer Protocol)라는 프로토콜을 사용한다. HTTP는 웹 브라우저와 웹 서버의 소통을 위해 디자인되었으며, HTTP를 이용해 주고받는 메세지를 HTTP 메세지라고 한다.

 

그렇다면 HTTP라는 통신 규약을 통해 우리는 어떻게 웹 페이지를 구성하고 작동시키는 걸까?

 


브라우저 작동 원리 

 

웹 브라우저는 앞서 언급됐던 TCP/IP, HTTP 프로토콜 등을 사용하는데, 우리가 보편적으로 사용하는 웹 사이트에 접근하기 위해서는 주소창에 각 속성에 맞는 입력값을 제공해야 해당 웹 사이트 또는 파일을 불러올 수 있는데, 이 입력값을  URL(Uniform Resource Locator) 또는  URI(Uniform Resource Identifier)라고 부른다.

 

URL은 네트워크 상에서 웹 페이지, 이미지, 동영상 등의 파일이 위치한 정보를 나타낸다. scheme, hosts, url-path로 구분 할 수 있다. 브라우저의 주소창에 입력한 URL은 서버가 제공되는 환경에 존재하는 파일의 위치를 나타내는데, 기본적인 보안의 일환으로 외부에서 서버의 폴더에 직접 접근이 가능한 경우는 거의 없다. 

 

URI는 일반적으로 URL의 기본 요소인 scheme, hosts, url-path에 더해 query, fragment를 포함한다.

 

각 요소들의 명칭과 예시, 그리고 해당 요소의 설명은 아래와 같다.

 

명칭(Property Name) 설명  예시
scheme 통신 방식(프로토콜)을 결정 file://, http://, https://
hosts 웹 서버의 이름, 도메인, IP를 사용한 주소 127.0.0.1, www.google.com
port 웹 서버에 접속하기 위한 통로 :80, :443, :3000
url-path 웹 서버의 루트 디렉토리(최상위 디렉토리)로부터 웹 페이지, 이미지, 동영상 등의 파일이 위치한 경로와 파일명 /search, /Users/username/Desktop
query 웹 서버에 보내는 추가적인 질문 q=JavaScript
fragment 일종의 북마크 기능, HTML 요소의 id를 전달하면 해당 요소가 있는 곳으로 스크롤 이동이 가능 #

 

각 요소들에 더해 표에 몇 가지 추가된 것들이 있다.

 

먼저 호스트의 예시에서 익숙한듯 익숙하지 않은 네 덩이의 숫자(127.0.0.1)를 확인할 수 있다. 해당하는 숫자들의 조합은 네트워크에 연결된 특정 PC의 주소를 나타내는데, 이를 IP 주소(Internet Protocol address)라고 부른다.

 

또한 앞서 나온 네 덩이의 숫자로 구분된 IP주소체계를 IPv4(Internet Protocol version 4, IP 주소체계의 네 번째 버전)라고 한다. 각 부분은 0부터 255까지의 숫자를 나타낼 수 있는데, 이를 통해 약 43억 개의 IP주소를 표현할 수 있다. 인터넷 보급률이 낮았던 초기에는 IPv4를 통해 네트워크에 연결된 PC에 주소를 할당하는 일이 가능했지만, 개인 PC의 보급으로 현재는 IPv4로 할당할 수 있는 PC가 한계를 넘어서게 되었다.

 

이에 따라 IPv6(IP version 6)가 생겼는데, 기존 IPv4가 2의 32승(약 43억 개)의 IP주소를 표현할 수 있는데 반해 IPv6는 2의 128승 개의 주소를 표현할 수 있다. 정확한 감이 안 왔는데, 한 블로그에 따르면  지구와 같은 행성이 21억 개가 있다고 가정하고 해당하는 각 지구의 인구 86억명에게 매년 43억개의 IP 주소를 43억년 동안 보급하면 고갈된다고 한다. 즉, 이번 생에는 IP 주소의 고갈을 더 이상 걱정하지 않아도 될 것 같다.

 

IP 주소 중 몇 가지는 용도가 정해져 있는데, 앞서 언급됐던 127.0.0.1(또는 localhost)은 현재 사용 중인 로컬 PC의 주소를 의미한다. 이 외에도, 0.0.0.0 또는 255.255.255.255는 브로드캐스트 주소로 로컬 네트워크에 접속된 모든 장치와 소통하는 주소이다.

 

 

리액트 프로젝트를 npx cretate-react-app 키워드를 통해 생성한 후 VS code로 라이브 서버를 실행시키면 위와 같은 주소창이 보인다.

 

hosts뒤에 따라 붙는 네자리 숫자는 IP주소가 가리키는 PC에 접속할 수 있는 통로(채널)을 의미하는데 이를 포트(PORT)라고 한다. 즉, 위 주소창을 통해 우리가 리액트를 실행했을 때에는 로컬 PC의 IP 주소로 접근하여, 3000번의 통로를 통해 실행 중인 리액트를 확인할 수 있다는 의미다.

 

포트 번호는 0~ 65535 까지 사용할 수 있으며, 그 중 0 ~ 1024번 까지의 포트 번호는 주요 통신을 위한 규약(프로토콜)에 따라 이미 정해져 있다. 그 중 많이 쓰이는 번호로는 22(SSH), 80(HTTP), 443(HTTPS)가 있다.

 

그렇다면 왜 우리는 특정 웹사이트에 접근할 때 IP 주소를 의미하는 숫자를 주소창에 입력하지 않아도 해당 웹 페이지에 접근할 수 있는걸까? 

간단한 예시를 생각해보자.

 

만약 우리가 택시를 타고 기사님께 "서울 중구 한강대로 405로 가주세요." 라고 한다면 기사님이 단번에 알아들으실 확률은 거의 없을 것이다.

 

하지만 우리가 "서울역으로 가주세요."라고 한다면 기사님은 쉽게 길을 찾아 우리를 서울역, 즉 서울 중구 한강대로 405로 데려다 주실 것이다.

 

이처럼 다소 복잡하고 한 눈에 파악하기 힘든 IP 주소를 대신해 간단하게 나타낼 수 있는 주소를 도메인 이름(Domain Name)이라고 한다.

 

nslookup 명령어를 통해 터미널에서 해당 웹 페이지의 IP 주소를 확인할 수 있다

 

위 예시처럼 터미널을 통해 해당 웹 페이지의 IP 주소를 찾을 수 있고, 해당 IP 주소를 입력하면 우리가 기존에 적었던 도메인 이름 "www.naver.com"처럼 우리가 목표로 하는 웹 페이지로 이동할 수 있다.

 

단, 모든 IP 주소가 도메인 이름을 가지는 것은 아니다. 우리가 사용하는 localhost의 경우 127.0.0.1을 대체하고 있지만, 이를 제외한 모든 도메인 이름은 일정 기간 동안 대여하여 사용하는 것이다.

 

주소창에 도메인 이름을 입력해 해당 사이트로 이동하기 위해서는 해당 도메인 이름과 매칭된 IP 주소를 확인해야 하는데, 네트워크에는 이를 위한 서버가 별도로 준비되어 있다. 이를 호스트의 도메인 이름을 IP 주소로 변환하거나 반대의 경우를 수행할 수 있도록 개발된 데이터베이스 시스템, DNS(Domain Name System)라고 한다.


HTTP 메세지: 요청(Requests)과 응답(Responses)

 

 

우리는 주소창을 통해 URL 또는 URI를 입력하면 우리가 원하는 웹 페이지에 도달할 수 있다는 것을 알았다.

 

여기서 한 걸음 더 나아가보자.

 

HTTP 메세지는 HTTP 프로토콜을 사용하는 메세지로, 클라이언트와 서버 사이에서 데이터가 교환되는 방식이다. 

 

이에 따라 주소창에 도메인 이름 또는 URL을 입력하고 해당 주소에 걸맞는 웹 사이트 또는 파일을 입력한 것도 하나의 HTTP "요청"을 담은 메세지다. 즉, 우리는 이미 별도의 개발자 과정을 거치지 않고도 웹 브라우저에서 매일 HTTP 메세지를 주고 받고 있던 것이다. 

 

하지만 눈에 보이지 않는 부분들이 있다.

 

HTTP 메세지는 요청(Requests) 응답(Responses) 두 가지 유형으로 나뉜다. 

 

요청과 응답은 각각 몇 줄의 텍스트 정보고 구성되는데, 다행스럽게도 여기까지 우리가 직접 개발할 필요는 없다. 구성 파일, API, 기타 인터페이스에서 HTTP 메세지를 자동으로 완성해주기 때문이다.

 

출처: MDN HTTP Messages (참조)

 

요청과 응답은 서로 유사한 구조를 가지고 다음과 같은 구성 요소를 가지고 있다.

 

구성 요소 설명
start line(요청)
status line (응답)
요청이나 응답의 상태를 나타내며, 항상 첫 번째 줄에 위치한다.
HTTP headers 요청을 지정하거나, 메세지에 포함된 본문을 설명하는 헤더의 집합
empty line 헤더와 본문을 구분하는 빈 줄
body 요청 또는 응답과 관련된 데이터 혹은 문서를 포함하고, 요청과 응답의 유형에 따라 선택적으로 사용한다.

 

앞서 언급했듯 우리가 HTTP 메세지를 개발할 필요는 없다.

 

하지만 HTTP 메세지를 통해 현재 수행중인 작업이 GET, PUT, POST 등 다양한 HTTP 메서드 중 무엇에 해당하는지, 사용하고 있는 프로토콜이 무엇인지 HTTP 메세지를 통해 알 수 있어야 한다. 이를 통해 우리가 사용하고자 하는 리소스에 대한 자세한 정보, 현재 서버를 통해 수행했던 작업 등을 알 수 있기 때문이다.

 

간단한 예시를 위해 현재 작성중인 티스토리 블로그 포스팅의 HTTP 메세지를 확인해보자. 메세지는 개발자 도구(F12 또는 ⌘Cmd + ⌥ Option + I (i))에서 Network 탭을 통해 확인할 수 있다. 

 

티스토리는 주기적으로 블로그 포스팅을 임시 저장 해놓는 기능이 있고, 해당 작업이 HTTP 메세지로 출력이 되고 있다.

 

 

해당 작업을 클릭하면 (HTTP) Headers를 비롯한 다양한 탭이 나오는데, 가장 먼저 보이는 HTTP Headers를 통해 autosave 작업이 현재 작성중인 (포스팅 되지 않은) 블로그 글을 HTTP 메서드 POST를 통해 작성 내용을 임시 저장 중인 것을 알 수 있다. 

 

 

이어서 Payload 탭에서는 HTTP 메세지의 body를 확인할 수 있다. body는 HTML 메세지가 전달하는 "내용"이다.

 

서버에 리소스를 요청하는 GET, DELETE, OPTIONS 등의 HTTP 메서드는 본문이 필요하지 않기 때문에 body를 가지고 있지 않지만 위 예시처럼 데이터를 업데이트 하거나 추가하는 POST 혹은 PUT 같은 메서드의 경우 body에 변경 또는 추가될 내용을 담고 있다.

 

이처럼 우리가 보이지 않는 부분, 즉 웹 페이지의 뒤(backend)에서 해당 웹 페이지에 필요한 리소스(데이터)를 네트워크를 통해 주고 받아 사용하고 있다. 

 


AJAX (Asynchronous JavaScript And XMLHttpRequest)

 

우리는 짧지만 간략하게나마 보이지 않는 곳에서 브라우저가 작동하는 방식에 대해 배울 수 있었다. 

 

그렇다면 이렇듯 실시간으로 업데이트되는 데이터를 브라우저의 보이는 곳(프론트엔드)에서는 어떻게 활용하고 있을까?

 

이에 대한 해답으로 우리는 AJAX를 사용하고 있다.

 

AJAX는 JavaScript, DOM, Fetch, XMLHttpRequest, HTML 등의 다양한 기술을 사용하는 웹 개발 기법으로, 웹 페이지에 필요한 부분에 필요한 데이터만 비동기적으로 받아와 화면에 보여줄 수 있다.

 

보다 나은 이해를 위해 간단한 예시를 통해 살펴보자.

 

위는 소셜 미디어 페이스북의 웹페이지다. 해당 웹 페이지에서 스크롤을 내릴 때마다 우리는 지속적으로 새로운 피드, 즉 데이터를 더 불러들여오고 있다. 하지만 웹 페이지는 새로운 피드를 불러온다고 해서 해당 페이지가 새로고침 되지 않는다. 

 

이는 AJAX 기법을 통해 스크롤의 끝에 도달할 때 쯤 Fetch를 통해 비동기적으로 데이터를 가져와서 업데이트하고 렌더링하기 때문이다. 

 

fetch('http://example.com/movies.json')
  .then((response) => response.json())
  .then((data) => console.log(data));

 

fetch() 메서드를 통해 위처럼 데이터를 가져올 수 있고, 우리는 여기에 맞는 어떠한 "조건"을 추가해 해당하는 조건마다 fetch를 실행시키고 재렌더링을 할 수 있도록 하면 된다. 더 자세한 건 이후 React 포스팅을 통해 설명하겠다.

 

중요한 점은 AJAX는 JavaScript와 DOM, 그리고 Fetch를 핵심적으로 활용해 페이지 이동 없이 서버로부터 필요한 데이터를 가져올 수 있다는 점이다. 또한, 앞서 언급했듯 비동기적인 방식을 취하고 있기 때문에 웹 페이지가 멈추지 않아 사용자가 불편함을 적게 느낄 수 있다.

 

하지만 AJAX는 검색 엔진Search Engine Optimization(SEO)에 불리하기 때문에 검색 사이트에서 상위 결과로 나오기 어렵다는 점과 뒤로가기 버튼을 눌렀을 때 완전히 초기의 상태로 되돌아가 일반적으로 사용자가 의도한 바와 다르게 작동하는 단점을 가지고 있다.

 

 


참조

'Front-End > 웹 (Web)' 카테고리의 다른 글

React(SPA)에서 Next.js(SSR)를 써야하는 이유  (0) 2023.07.21
[Web] 웹 표준과 접근성  (0) 2022.11.20
[HTTP/네트워크] REST API  (0) 2022.11.05
[Web] UI와 UX  (0) 2022.11.03
[HTTP/네트워크] 웹 애플리케이션 구조  (0) 2022.10.17

댓글