naver.com을 입력한 순간부터 HTML을 받기까지
web | 2026년 8월 12일
브라우저 주소창에 naver.com을 입력하고 Enter를 누르면 잠시 뒤 네이버의 첫 화면이 나타난다.
사용자가 한 일은 열 글자를 입력한 것뿐이다. 하지만 브라우저는 그 짧은 시간 동안 입력값을 URL로 해석하고, 서버의 주소를 알아낸 뒤, 안전한 연결을 만들고, 문서를 요청한다. 우리가 당연하게 여기는 한 번의 접속은 여러 계층이 차례로 협력한 결과다.
이 글에서는 주소창에 naver.com을 입력한 순간부터 브라우저가 첫 HTML 응답을 받기까지의 과정을 따라가 본다. HTML 이후 화면을 그리는 렌더링 과정은 다음 이야기로 남겨 둔다.
naver.com은 아직 완전한 URL이 아니다
naver.com은 네이버라는 대상을 식별하는 도메인 이름이다. 반면 브라우저가 실제 요청에 사용하는 URL에는 어떤 방식으로, 어느 위치의 자원을 요청할지에 관한 정보가 더 들어간다.
https://www.naver.com/
└─┬─┘ └────┬────┘ └┬┘
scheme host path
https는 통신 방식인 스킴이고, www.naver.com은 접속할 호스트, /는 요청할 경로다. 주소창에는 스킴과 경로를 생략해도 브라우저가 이를 보완한다. 검색어인지 주소인지 판단하고, HTTPS로 접속할 수 있는 주소 형태로 만든다.
이때 최종 URL이 처음 입력한 문자열과 반드시 같지는 않다. 서버의 정책에 따라 naver.com에서 www.naver.com으로 이동하거나 다른 경로로 리다이렉트될 수 있다. 중요한 것은 브라우저가 먼저 입력값을 네트워크 요청에 사용할 수 있는 URL로 바꾼다는 점이다.
도메인은 사람이 읽고, 네트워크는 IP 주소를 사용한다
URL을 해석했다고 바로 네이버에 요청을 보낼 수 있는 것은 아니다. 사람에게 naver.com은 기억하기 좋은 이름이지만, 네트워크에서 목적지를 찾으려면 223.130.200.104와 같은 IP 주소가 필요하다.
도메인 이름을 IP 주소로 변환하는 역할을 DNS가 맡는다. 흔히 DNS를 인터넷의 전화번호부라고 부르는 이유다.
브라우저는 곧바로 멀리 있는 DNS 서버부터 찾아가지 않는다. 이미 알고 있는 답이 가까운 곳에 있는지 먼저 확인한다. 브라우저와 운영체제의 DNS 캐시, 로컬 설정 등을 살핀 뒤 답이 없다면 사용 중인 DNS 리졸버에 질의한다. 리졸버는 가정의 공유기, 통신사, 회사 네트워크 또는 사용자가 지정한 공개 DNS가 제공할 수 있다.
리졸버에도 답이 없다면 도메인의 계층을 따라 주소를 찾는다.
Root DNS
→ .com을 담당하는 TLD DNS
→ naver.com을 담당하는 권한 있는 DNS
→ naver.com의 IP 주소
루트 DNS는 .com을 담당하는 서버를 알려 주고, .com의 TLD DNS는 naver.com을 담당하는 권한 있는 DNS를 알려 준다. 마지막으로 권한 있는 DNS가 해당 호스트의 주소 정보를 제공한다. 실제 조회에서는 이전에 저장된 캐시 덕분에 이 모든 단계를 매번 거치지는 않는다.
DNS 응답에는 IPv4 주소를 나타내는 A, IPv6 주소를 나타내는 AAAA, 다른 도메인을 가리키는 CNAME 등의 레코드가 사용될 수 있다. 각 응답에는 얼마 동안 결과를 저장해도 되는지 나타내는 TTL도 포함된다. 그래서 같은 주소를 다시 방문할 때는 DNS 조회 과정이 짧아질 수 있다.
여기서 얻은 IP 주소가 네이버의 애플리케이션 서버 한 대를 직접 가리킨다고 단정할 수는 없다. 대규모 서비스는 요청을 가까운 위치에서 처리하거나 트래픽을 분산하기 위해 CDN, 프록시, 로드 밸런서 같은 여러 계층을 둘 수 있다. DNS는 사용자가 최종적으로 연결해야 할 진입점을 알려 줄 뿐, 그 뒤의 내부 구조를 모두 보여 주지는 않는다.
주소를 알았다면 연결을 만든다
목적지의 IP 주소를 알아냈으니 이제 데이터를 주고받을 통로가 필요하다.
HTTP/1.1과 HTTP/2는 일반적으로 TCP 위에서 동작한다. TCP 연결은 흔히 3-way handshake라 부르는 세 단계로 시작한다.
브라우저 ── SYN ───────→ 서버
브라우저 ←─ SYN + ACK ── 서버
브라우저 ── ACK ───────→ 서버
브라우저가 연결을 요청하고, 서버가 이를 확인하면서 자신의 연결 요청을 보내고, 브라우저가 다시 확인한다. 이 과정을 통해 양쪽이 서로 데이터를 주고받을 준비가 되었음을 확인한다.
TCP는 데이터가 순서대로 도착했는지 확인하고, 손실된 데이터가 있으면 다시 전송한다. 웹 문서를 안정적으로 전달할 수 있는 대신, 새 연결을 만드는 데는 브라우저와 서버 사이를 오가는 시간이 필요하다.
다만 모든 요청이 반드시 TCP를 사용하는 것은 아니다. HTTP/3는 UDP 위에 구현된 QUIC을 사용한다. QUIC은 연결과 암호화에 필요한 절차를 통합하고, 여러 요청 중 하나에서 발생한 손실이 다른 요청까지 막는 문제를 줄인다. 브라우저와 서버가 지원하는 프로토콜, 이전 접속에서 얻은 정보 등에 따라 실제 연결 방식이 결정된다.
HTTPS는 서버의 신원을 확인한다
연결을 만들었다고 바로 HTTP 요청을 보내는 것은 아니다. URL의 스킴이 https라면 브라우저와 서버는 TLS를 통해 암호화된 연결을 준비해야 한다.
TLS에는 세 가지 중요한 목적이 있다.
- 지금 연결한 상대가 요청한 도메인의 서버인지 확인한다.
- 통신 내용을 제삼자가 읽지 못하도록 암호화한다.
- 전송 중 데이터가 바뀌지 않았는지 확인한다.
TLS 핸드셰이크 과정에서 브라우저와 서버는 사용할 TLS 버전과 암호화 방식을 협의한다. 서버는 자신의 공개 키와 신원 정보가 담긴 인증서를 전달한다. 브라우저는 인증서의 도메인, 유효 기간, 인증 기관으로 이어지는 서명 체인을 검사한다.
검증을 마치면 양쪽은 이후 통신을 암호화하는 데 사용할 키를 안전하게 만든다. 그 뒤에야 브라우저가 보내는 경로, 헤더, 쿠키와 서버가 돌려주는 HTML을 암호화된 형태로 주고받을 수 있다.
하나의 IP 주소가 여러 도메인을 서비스하는 경우도 있다. 브라우저는 TLS 연결 초기에 SNI를 통해 접속하려는 호스트 이름을 알리고, 서버는 그에 맞는 인증서를 선택한다. 연결이 만들어진 뒤 HTTP 요청에 포함되는 Host 또는 HTTP/2 이후의 :authority 정보는 서버가 어떤 도메인의 자원을 요청받았는지 구분하는 데 사용된다.
연결 위로 HTTP 요청을 보낸다
DNS로 목적지를 찾고 TLS 연결까지 준비했다. 이제 브라우저는 비로소 네이버의 첫 문서를 요청한다.
요청의 의미를 단순화하면 다음과 같다.
GET / HTTP/2
Host: www.naver.com
Accept: text/html
Accept-Encoding: gzip, br
User-Agent: ...
Cookie: ...
GET /는 루트 경로의 자원을 달라는 뜻이다. 헤더에는 받을 수 있는 콘텐츠와 압축 방식, 브라우저 정보 등이 담긴다. 이전에 방문한 적이 있고 유효한 쿠키가 있다면 쿠키도 함께 전송될 수 있다.
HTTPS에서는 이 요청 내용이 그대로 노출되지 않고 앞에서 만든 TLS 연결을 통해 암호화된다. 다만 통신에 필요한 IP 주소 같은 일부 네트워크 정보까지 모두 숨겨지는 것은 아니다.
요청 데이터는 여러 패킷으로 나뉘어 네트워크를 이동한다. 패킷은 공유기와 통신사의 라우터 등 여러 장비를 거쳐 목적지에 도착한다. 각 라우터는 전체 여행 경로를 미리 알고 움직이기보다, 패킷의 목적지 IP 주소를 보고 다음으로 보낼 위치를 결정한다.
요청은 한 대의 서버로 곧장 가지 않을 수 있다
대규모 웹 서비스 앞에는 다양한 중간 계층이 존재할 수 있다. 사용자와 가까운 엣지 서버가 요청을 먼저 받고, 방화벽이 비정상적인 트래픽을 걸러 내며, 로드 밸런서가 여러 서버 가운데 요청을 처리할 대상을 정할 수 있다.
브라우저
→ 인터넷
→ 엣지·프록시
→ 로드 밸런서
→ 애플리케이션 서버
이 구조는 일반적인 예시일 뿐 실제 네이버의 내부 요청 경로를 의미하지는 않는다. 서비스 내부 구조는 외부에서 보이지 않고, 운영 상황에 따라 달라질 수도 있다.
브라우저의 관점에서 중요한 것은 요청을 받은 시스템이 적절한 응답을 돌려준다는 사실이다. 서버는 요청 경로와 쿠키 등을 바탕으로 응답을 만들거나, 브라우저가 다른 URL을 요청하도록 리다이렉트 응답을 보낼 수 있다.
리다이렉트가 발생하면 브라우저는 응답의 Location 헤더에 적힌 새 URL을 따라간다. 새 호스트라면 DNS 조회와 연결 과정이 추가로 필요할 수 있고, 같은 호스트이면서 기존 연결을 재사용할 수 있다면 일부 절차는 생략된다.
서버가 HTML을 응답한다
요청이 정상적으로 처리되면 서버는 상태 코드와 헤더, 본문으로 이루어진 HTTP 응답을 보낸다.
HTTP/2 200 OK
Content-Type: text/html; charset=UTF-8
Content-Encoding: br
Cache-Control: ...
<!doctype html>
<html>...</html>
200 OK는 요청이 정상적으로 처리되었다는 뜻이고, Content-Type은 본문이 HTML 문서임을 알려 준다. Content-Encoding이 있다면 전송 크기를 줄이기 위해 본문이 압축되었다는 의미다. 캐시 관련 헤더는 브라우저가 이 응답을 저장하고 다시 사용할 수 있는 조건을 설명한다.
HTML은 반드시 하나의 덩어리로 한 번에 도착하지 않는다. 브라우저는 네트워크를 통해 나누어 도착하는 데이터를 받으며 압축을 풀고 HTML을 읽기 시작할 수 있다. 문서 안에서 CSS, JavaScript, 이미지 같은 다른 자원을 발견하면 각각의 URL을 해석해 추가 요청을 준비한다.
이제 브라우저는 HTML을 화면으로 바꾸는 단계에 들어간다. DOM과 CSSOM을 만들고, 레이아웃을 계산하고, 픽셀을 그리는 렌더링 과정이다. 그것은 naver.com을 찾아가는 네트워크 여정의 끝이자, 화면을 만드는 새로운 여정의 시작이다.
다시 방문하면 모든 과정을 반복할까?
첫 방문과 다음 방문의 과정은 같지 않을 수 있다.
DNS 응답이 아직 유효하면 저장된 IP 주소를 사용할 수 있다. 기존 TCP 또는 QUIC 연결이 살아 있다면 새 연결을 만드는 절차를 줄일 수 있고, TLS 세션을 재개해 암호화 연결에 필요한 비용을 낮출 수도 있다. HTML이나 다른 자원이 HTTP 캐시에 남아 있고 재사용 조건을 만족한다면 서버에서 본문 전체를 다시 받지 않아도 된다.
브라우저가 여러 계층의 캐시와 연결 재사용을 활용하는 이유는 단순하다. 네트워크에서 가장 빠른 요청은 멀리 다녀오지 않아도 되는 요청이기 때문이다.
주소 하나 뒤에 숨어 있던 과정
지금까지의 흐름을 한 줄로 정리하면 다음과 같다.
주소창 입력
→ URL 해석
→ DNS 조회
→ IP 주소 획득
→ TCP 또는 QUIC 연결
→ TLS 핸드셰이크
→ HTTP 요청
→ 서버 처리
→ HTTP 응답
→ HTML 수신
주소창에 입력한 naver.com이 화면으로 나타나기까지 도메인, DNS, IP, 전송 프로토콜, TLS, HTTP가 각자의 역할을 수행한다. 각 계층은 서로 다른 문제를 해결하지만, 사용자에게는 하나의 자연스러운 동작처럼 보인다.
웹을 이해한다는 것은 이 당연해 보이는 순간을 여러 단계로 나누어 보는 일인지도 모른다. 화면이 늦게 뜨거나 특정 환경에서만 접속에 실패할 때도, 어느 단계에서 시간이 걸리고 문제가 생겼는지 나누어 보면 원인에 조금 더 가까이 갈 수 있다.