ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 주소창에 URL을 입력하면 무슨 일이 일어날까?
    웹 개발 2026. 4. 20. 15:35

    우리는 매일 브라우저 주소창에 주소를 입력합니다.

    예를 들어 이런 주소를 입력한다고 해보겠습니다.

    https://www.example.com

    그리고 엔터를 누르면 잠시 뒤 화면에 웹페이지가 나타납니다.

    사용자 입장에서는 아주 단순합니다.

    1. 주소를 입력한다.
    2. 엔터를 누른다.
    3. 화면이 뜬다.

    하지만 개발자의 관점에서 보면 이 짧은 순간에 꽤 많은 일이 일어납니다.

    브라우저는 주소를 해석하고, 서버의 위치를 찾고, 서버와 연결하고, 요청을 보내고, 응답을 받은 뒤, HTML/CSS/JavaScript를 해석해서 화면을 그립니다.

    이번 글에서는 주소창에 URL을 입력했을 때 어떤 일이 일어나는지 큰 흐름부터 차근차근 정리해보겠습니다.


    전체 흐름

    먼저 전체 과정을 아주 단순하게 표현하면 다음과 같습니다.

    사용자
      ↓
    브라우저 주소창에 URL 입력
      ↓
    브라우저가 URL 해석
      ↓
    DNS로 서버 IP 주소 찾기
      ↓
    서버와 연결
      ↓
    HTTP 요청 전송
      ↓
    서버가 요청 처리
      ↓
    HTTP 응답 수신
      ↓
    HTML, CSS, JavaScript 해석
      ↓
    화면 렌더링

    조금 길어 보이지만 핵심은 단순합니다.

    브라우저는 사용자를 대신해서 서버에 "이 페이지 주세요"라고 요청하고, 서버는 "여기 있습니다"라고 응답합니다. 그 응답을 브라우저가 해석해서 우리가 보는 화면으로 만들어주는 것입니다.


    URL이란?

    주소창에 입력하는 https://www.example.com 같은 값을 URL이라고 부릅니다.

    URL은 Uniform Resource Locator의 줄임말입니다. 쉽게 말하면 인터넷에 있는 자원의 주소입니다.

    여기서 자원은 HTML 페이지일 수도 있고, 이미지일 수도 있고, CSS 파일이나 JavaScript 파일일 수도 있습니다.

    예를 들어 아래 URL을 보겠습니다.

    https://www.example.com/products?id=123

    대략 이렇게 나눠볼 수 있습니다.

    https://        → 어떤 방식으로 통신할 것인가
    www.example.com → 어느 서버에 요청할 것인가
    /products       → 서버의 어떤 경로를 요청할 것인가
    ?id=123         → 요청에 함께 보낼 추가 정보

    브라우저는 사용자가 입력한 문자열을 그냥 통째로 서버에 보내지 않습니다. 먼저 URL을 분석해서 어떤 프로토콜을 사용할지, 어떤 도메인으로 접근해야 하는지, 어떤 경로를 요청해야 하는지 파악합니다.

    여기서 https는 HTTPS라는 방식으로 통신하겠다는 뜻입니다. HTTPS는 HTTP 통신을 암호화해서 중간에서 내용을 쉽게 훔쳐보거나 변조하지 못하게 해주는 방식입니다.


    브라우저는 먼저 주소를 해석한다

    브라우저 주소창은 생각보다 똑똑합니다.

    우리가 주소창에 devlov.tistory.com이라고 입력하면 브라우저는 이것을 웹사이트 주소로 보고 접속을 시도합니다. 반대로 웹개발이란이라고 입력하면 검색어로 판단해서 기본 검색 엔진으로 검색합니다.

    브라우저는 입력값을 보고 대략 이런 판단을 합니다.

    이건 검색어인가?
    이건 URL인가?
    프로토콜이 생략되어 있나?
    도메인은 무엇인가?
    경로는 무엇인가?

    최근 브라우저에서는 https://를 직접 입력하지 않아도 자동으로 HTTPS 접속을 먼저 시도하는 경우가 많습니다.

    즉, 사용자는 example.com만 입력했지만 브라우저는 내부적으로 https://example.com처럼 해석해서 접속을 시도할 수 있습니다.


    DNS: 도메인을 IP 주소로 바꾸기

    URL에서 가장 중요한 부분 중 하나는 도메인입니다.

    www.example.com

    사람은 이런 문자 주소를 읽기 편합니다. 하지만 컴퓨터끼리 통신할 때는 보통 IP 주소가 필요합니다.

    예를 들어 어떤 서버는 이런 IP 주소를 가질 수 있습니다.

    93.184.216.34

    사람이 매번 이런 숫자를 외우기는 어렵습니다. 그래서 www.example.com 같은 도메인을 사용합니다.

    DNS는 Domain Name System의 줄임말입니다. 쉽게 말하면 도메인 이름을 IP 주소로 바꿔주는 시스템입니다.

    비유하자면 전화번호부와 비슷합니다.

    사람이 기억하기 쉬운 이름: www.example.com
    실제 연락처: 93.184.216.34

    브라우저는 서버에 요청을 보내기 전에 먼저 이 도메인이 어떤 IP 주소를 가리키는지 알아내야 합니다.

    DNS 조회는 대략 이런 식으로 진행됩니다.

    브라우저: www.example.com의 IP 주소가 뭐지?
    DNS: 이 도메인은 93.184.216.34를 가리켜.
    브라우저: 이제 이 IP 주소로 접속해야겠다.

    실제로는 브라우저, 운영체제, 공유기, 통신사 DNS 서버, 권한 있는 DNS 서버 등 여러 단계가 관여할 수 있습니다. 하지만 입문 단계에서는 "DNS는 도메인을 IP 주소로 바꿔준다" 정도로 이해해도 충분합니다.


    서버와 연결하기

    브라우저가 서버의 IP 주소를 알게 되면 이제 서버와 연결을 시도합니다.

    웹에서 전통적으로 많이 쓰이는 연결은 TCP 연결입니다. TCP는 데이터를 안정적으로 주고받기 위한 통신 방식입니다.

    HTTPS를 사용한다면 TCP 연결 이후에 TLS라는 암호화 과정도 진행됩니다.

    흐름을 단순화하면 다음과 같습니다.

    브라우저
      ↓
    서버 IP 주소로 TCP 연결 시도
      ↓
    HTTPS라면 TLS 암호화 연결 설정
      ↓
    HTTP 요청을 보낼 준비 완료

    여기서 헷갈릴 수 있는 부분이 있습니다.

    HTTP와 TCP는 같은 것이 아닙니다.

    TCP는 데이터를 안정적으로 전달하기 위한 아래쪽 통신 방식에 가깝고, HTTP는 웹에서 클라이언트와 서버가 요청과 응답을 주고받기 위한 약속입니다.

    비유하자면 TCP는 택배 운송 시스템이고, HTTP는 택배 상자 안에 들어 있는 주문서 양식에 가깝습니다.

    다만 최근에는 HTTP/3처럼 TCP 대신 QUIC이라는 방식을 사용하는 경우도 있습니다. 하지만 처음 웹의 흐름을 이해할 때는 "브라우저가 서버와 연결한 뒤 HTTP 요청을 보낸다"는 큰 흐름을 먼저 잡는 것이 좋습니다.


    HTTP 요청 보내기

    서버와 연결되면 브라우저는 HTTP 요청을 보냅니다.

    HTTP 요청은 브라우저가 서버에게 보내는 메시지입니다.

    예를 들면 이런 의미입니다.

    서버야, / 경로에 해당하는 페이지를 보내줘.
    나는 HTML을 이해할 수 있어.
    나는 이런 브라우저를 사용하고 있어.
    쿠키도 같이 보낼게.

    실제 HTTP 요청은 대략 이런 형태를 가질 수 있습니다.

    GET / HTTP/1.1
    Host: www.example.com
    User-Agent: Mozilla/5.0
    Accept: text/html

    여기서 GET은 HTTP 메서드입니다.

    GET은 서버에서 데이터를 가져올 때 주로 사용합니다. 주소창에 URL을 입력해서 페이지를 여는 것은 대부분 GET 요청입니다.

    다른 대표적인 메서드로는 POST가 있습니다. POST는 로그인, 회원가입, 글 작성처럼 서버에 데이터를 보내야 하는 상황에서 자주 사용합니다.

    즉, 브라우저가 서버에 보내는 요청은 그냥 "접속합니다"가 아니라 꽤 구체적인 메시지입니다.

    어떤 방식으로 요청할지
    어떤 경로를 요청할지
    어떤 도메인에 대한 요청인지
    브라우저가 어떤 데이터를 받을 수 있는지
    쿠키나 인증 정보가 있는지

    이런 정보들이 HTTP 요청에 담깁니다.


    서버는 요청을 처리한다

    브라우저의 요청을 받은 서버는 이제 요청을 처리합니다.

    서버가 하는 일은 서비스마다 다릅니다.

    단순한 정적 웹사이트라면 서버는 이미 만들어져 있는 HTML 파일을 그대로 돌려줄 수 있습니다.

    요청: /
    응답: index.html 파일

    반대로 로그인한 사용자의 마이페이지처럼 사용자마다 다른 화면을 보여줘야 한다면 서버는 더 많은 일을 해야 합니다.

    예를 들어 이런 과정이 있을 수 있습니다.

    1. 요청에 포함된 쿠키를 확인한다.
    2. 이 사용자가 로그인한 사용자인지 확인한다.
    3. 데이터베이스에서 사용자 정보를 가져온다.
    4. 필요한 데이터를 조합한다.
    5. HTML 또는 JSON 응답을 만든다.
    6. 브라우저에 응답을 보낸다.

    이때 백엔드 개발자가 작성한 코드가 실행됩니다.

    Node.js, Java Spring, Ruby on Rails, Django, NestJS 같은 서버 기술들은 결국 이런 요청을 받아서 응답을 만들어내기 위해 사용됩니다.

    서버 개발을 아주 단순하게 말하면 다음과 같습니다.

    요청을 받는다.
    필요한 일을 한다.
    응답을 보낸다.

    물론 실제 서비스에서는 인증, 권한, 데이터베이스, 캐시, 외부 API, 로그, 에러 처리, 보안 등 훨씬 많은 요소가 들어갑니다. 하지만 출발점은 항상 요청과 응답입니다.


    HTTP 응답 받기

    서버가 요청을 처리하면 브라우저에 HTTP 응답을 보냅니다.

    HTTP 응답은 서버가 브라우저에게 보내는 메시지입니다.

    예를 들면 이런 의미입니다.

    요청한 페이지를 찾았어.
    상태는 성공이야.
    응답 내용은 HTML이야.
    아래 내용을 화면에 그리면 돼.

    실제 응답은 대략 이런 형태를 가질 수 있습니다.

    HTTP/1.1 200 OK
    Content-Type: text/html; charset=UTF-8
    
    <!doctype html>
    <html>
      <head>
        <title>Example</title>
      </head>
      <body>
        <h1>Hello Web</h1>
      </body>
    </html>

    여기서 200 OK는 상태 코드입니다.

    상태 코드는 요청이 어떻게 처리되었는지 알려줍니다.

    대표적인 상태 코드는 다음과 같습니다.

    200: 성공
    301, 302: 다른 주소로 이동
    400: 잘못된 요청
    401: 인증 필요
    403: 접근 권한 없음
    404: 찾을 수 없음
    500: 서버 내부 오류

    우리가 흔히 보는 "404 Not Found"는 브라우저가 요청한 자원을 서버에서 찾지 못했다는 뜻입니다.

    반대로 "500 Internal Server Error"는 서버 안에서 문제가 발생했다는 뜻입니다. 이 경우에는 프론트엔드 코드 문제가 아니라 백엔드 코드, 서버 설정, 데이터베이스 연결 등 서버 쪽 문제일 가능성이 큽니다.


    브라우저는 HTML을 읽기 시작한다

    브라우저가 서버로부터 HTML 응답을 받으면 이제 화면을 만들기 시작합니다.

    HTML은 웹페이지의 구조를 표현합니다.

    예를 들어 이런 HTML이 있다고 해보겠습니다.

    <!doctype html>
    <html>
      <head>
        <title>나의 웹페이지</title>
        <link rel="stylesheet" href="/style.css">
      </head>
      <body>
        <h1>안녕하세요</h1>
        <script src="/main.js"></script>
      </body>
    </html>

    브라우저는 HTML을 위에서 아래로 읽어가며 문서 구조를 파악합니다.

    이 과정에서 DOM이라는 구조를 만듭니다.

    DOM은 Document Object Model의 줄임말입니다. 쉽게 말하면 HTML 문서를 브라우저가 다루기 쉬운 객체 구조로 바꾼 것입니다.

    HTML이 글로 적힌 문서라면, DOM은 그 문서를 브라우저가 이해하고 조작할 수 있게 만든 나무 구조입니다.

    html
     ├─ head
     │   ├─ title
     │   └─ link
     └─ body
         ├─ h1
         └─ script

    JavaScript에서 document.querySelector() 같은 코드를 사용할 수 있는 이유도 브라우저가 HTML을 DOM으로 만들어두기 때문입니다.


    CSS 파일을 다시 요청한다

    HTML 안에는 CSS 파일을 불러오는 코드가 있을 수 있습니다.

    <link rel="stylesheet" href="/style.css">

    브라우저는 이 코드를 발견하면 다시 서버에 요청을 보냅니다.

    /style.css 파일을 주세요.

    그러면 서버는 CSS 파일을 응답으로 보내줍니다.

    CSS는 화면의 모양을 결정합니다.

    h1 {
      color: red;
      font-size: 32px;
    }

    브라우저는 CSS를 해석해서 CSSOM이라는 구조를 만듭니다.

    CSSOM은 CSS Object Model의 줄임말입니다. DOM이 문서의 구조라면, CSSOM은 각 요소에 어떤 스타일을 적용해야 하는지에 대한 정보입니다.

    브라우저는 DOM과 CSSOM을 조합해서 실제로 화면에 보여줄 요소와 스타일을 계산합니다.


    JavaScript 파일도 다시 요청한다

    HTML 안에는 JavaScript 파일을 불러오는 코드도 있을 수 있습니다.

    <script src="/main.js"></script>

    브라우저는 이 코드를 만나면 /main.js 파일도 서버에 요청합니다.

    JavaScript는 HTML과 CSS를 조작하거나, 사용자 이벤트를 처리하거나, 서버에 추가 데이터를 요청하는 데 사용됩니다.

    예를 들어 버튼을 클릭했을 때 화면의 문구를 바꾸는 일은 JavaScript가 할 수 있습니다.

    document.querySelector("h1").textContent = "반갑습니다";

    여기서 중요한 점은 브라우저가 처음 받은 HTML 하나만으로 모든 화면을 완성하는 경우는 많지 않다는 것입니다.

    대부분의 웹페이지는 HTML을 받은 뒤 CSS, JavaScript, 이미지, 폰트 같은 자원을 추가로 요청합니다.

    그래서 실제 흐름은 이렇게 됩니다.

    1. HTML 요청
    2. HTML 응답
    3. HTML 안에서 CSS, JS, 이미지 주소 발견
    4. CSS, JS, 이미지 추가 요청
    5. 각 파일 응답
    6. 화면 구성

    웹페이지 하나를 여는 것처럼 보이지만, 내부적으로는 여러 번의 요청과 응답이 오가는 것입니다.


    브라우저가 화면을 그리는 과정

    브라우저가 화면을 그리는 과정을 렌더링이라고 부릅니다.

    단순화하면 다음과 같은 흐름입니다.

    HTML 파싱
      ↓
    DOM 생성
      ↓
    CSS 파싱
      ↓
    CSSOM 생성
      ↓
    DOM + CSSOM 조합
      ↓
    Render Tree 생성
      ↓
    Layout
      ↓
    Paint

    각 단계를 조금 더 쉽게 설명해보겠습니다.

    DOM 생성

    브라우저가 HTML을 읽고 문서 구조를 만듭니다.

    이 페이지에는 제목이 있고, 문단이 있고, 버튼이 있구나.

    CSSOM 생성

    브라우저가 CSS를 읽고 스타일 정보를 만듭니다.

    제목은 빨간색이고, 글자 크기는 32px이구나.

    Render Tree 생성

    브라우저가 DOM과 CSSOM을 합쳐서 실제로 화면에 보여줄 요소 목록을 만듭니다.

    여기서 display: none처럼 화면에 보이지 않는 요소는 렌더 트리에서 제외될 수 있습니다.

    Layout

    각 요소가 화면의 어디에, 어떤 크기로 배치될지 계산합니다.

    제목은 위에서 20px 떨어진 곳에 놓고,
    너비는 화면 전체를 사용하고,
    버튼은 그 아래에 배치하자.

    Paint

    계산이 끝나면 실제 픽셀로 화면에 그립니다.

    우리가 보는 웹페이지는 이 과정을 거쳐 나타납니다.


    개발자 도구로 직접 확인하기

    이 흐름은 브라우저 개발자 도구에서 직접 확인할 수 있습니다.

    Chrome 기준으로는 다음 순서로 볼 수 있습니다.

    1. 웹페이지를 연다.
    2. F12 또는 우클릭 → 검사를 누른다.
    3. Network 탭을 연다.
    4. 새로고침한다.

    그러면 브라우저가 서버에 보낸 요청 목록이 보입니다.

    여기서 확인할 수 있는 것들이 있습니다.

    문서 요청: HTML
    스타일 요청: CSS
    스크립트 요청: JavaScript
    이미지 요청: PNG, JPG, WebP
    폰트 요청: WOFF, WOFF2
    API 요청: JSON

    각 요청을 클릭하면 더 자세한 정보도 볼 수 있습니다.

    Headers: 요청/응답 헤더
    Preview: 응답 미리보기
    Response: 실제 응답 내용
    Timing: 요청에 걸린 시간

    처음에는 복잡해 보이지만, Network 탭을 보면 "웹페이지 하나를 열 때 정말 많은 요청이 발생하는구나"라는 것을 바로 느낄 수 있습니다.

    웹개발을 공부할 때 개발자 도구의 Network 탭은 아주 중요합니다. 화면에 문제가 생겼을 때 이 요청이 성공했는지, 서버가 어떤 응답을 보냈는지, 상태 코드는 무엇인지 확인할 수 있기 때문입니다.


    예시로 다시 정리하기

    사용자가 주소창에 아래 주소를 입력했다고 해보겠습니다.

    https://www.example.com/products

    브라우저와 서버 사이에서는 대략 이런 일이 일어납니다.

    사용자: 주소창에 URL 입력
    
    브라우저: 이 주소는 HTTPS를 사용하는구나.
    브라우저: 도메인은 www.example.com이구나.
    브라우저: DNS에게 IP 주소를 물어봐야겠다.
    
    DNS: www.example.com의 IP는 93.184.216.34야.
    
    브라우저: 이제 이 IP의 서버와 연결해야겠다.
    브라우저: HTTPS니까 암호화 연결도 준비해야겠다.
    
    브라우저 → 서버:
    GET /products HTTP 요청
    
    서버: /products 페이지 요청이 들어왔네.
    서버: 필요한 데이터를 준비해야겠다.
    서버: HTML을 만들어서 응답해야겠다.
    
    서버 → 브라우저:
    200 OK
    HTML 응답
    
    브라우저: HTML을 읽어야겠다.
    브라우저: CSS 파일이 필요하네. 다시 요청하자.
    브라우저: JavaScript 파일도 필요하네. 다시 요청하자.
    브라우저: 이미지도 필요하네. 다시 요청하자.
    
    브라우저: DOM과 CSSOM을 만들고 화면을 그리자.
    
    사용자: 웹페이지가 보인다.

    사용자 눈에는 "주소 입력 후 페이지 표시"로 보이지만, 내부적으로는 이런 여러 단계가 지나갑니다.


    프론트엔드와 백엔드는 어디에 있을까?

    이 흐름을 알면 프론트엔드와 백엔드의 역할도 조금 더 명확해집니다.

    프론트엔드는 브라우저에서 실행되는 화면과 상호작용을 담당합니다.

    HTML
    CSS
    JavaScript
    React, Vue 같은 프론트엔드 라이브러리
    브라우저에서 보이는 화면
    사용자 클릭, 입력, 스크롤 처리

    백엔드는 서버에서 요청을 처리하고 응답을 만듭니다.

    HTTP 요청 처리
    로그인 확인
    데이터베이스 조회
    비즈니스 로직 실행
    HTML 또는 JSON 응답 생성
    서버 로그와 에러 처리

    프론트엔드와 백엔드는 완전히 따로 노는 것이 아닙니다. 브라우저가 서버에 요청을 보내고, 서버가 응답을 보내는 HTTP 흐름 위에서 서로 연결됩니다.

    그래서 웹개발을 이해하려면 HTML, CSS, JavaScript만 아는 것도 부족하고, 서버만 아는 것도 부족합니다. 최소한 "브라우저가 서버에 요청하고 서버가 응답한다"는 흐름은 함께 이해해야 합니다.


    왜 이 흐름을 알아야 할까?

    처음 개발을 공부할 때는 React, Spring, Next.js, NestJS 같은 기술 이름이 먼저 눈에 들어옵니다.

    하지만 이런 기술들은 모두 웹의 기본 흐름 위에서 동작합니다.

    React로 만든 화면도 결국 브라우저에서 HTML, CSS, JavaScript로 동작합니다.

    Spring이나 NestJS로 만든 서버도 결국 브라우저나 다른 클라이언트로부터 HTTP 요청을 받고 HTTP 응답을 보냅니다.

    AWS, Nginx, Docker 같은 기술을 배우더라도 결국 사용자의 요청이 어떤 서버로 전달되고, 서버가 어떤 응답을 돌려주는지 이해해야 합니다.

    이 흐름을 알고 있으면 문제가 생겼을 때 어디를 봐야 할지 감이 생깁니다.

    예를 들어 화면이 안 뜬다고 해보겠습니다.

    그때 확인할 수 있는 질문들이 생깁니다.

    URL을 잘못 입력한 것은 아닐까?
    DNS가 제대로 연결되어 있을까?
    서버에 연결은 되고 있을까?
    HTTPS 인증서 문제는 아닐까?
    HTTP 상태 코드가 404인가, 500인가?
    HTML은 받았는데 CSS가 깨진 것은 아닐까?
    JavaScript 에러 때문에 화면이 멈춘 것은 아닐까?
    API 요청이 실패한 것은 아닐까?

    이 질문들을 던질 수 있게 되는 것만으로도 디버깅 실력이 크게 달라집니다.


    마무리

    주소창에 URL을 입력하면 브라우저는 단순히 "사이트를 연다"가 아니라 여러 단계를 거쳐 웹페이지를 화면에 보여줍니다.

    핵심 흐름은 다음과 같습니다.

    URL 입력
    → URL 해석
    → DNS 조회
    → 서버 연결
    → HTTP 요청
    → 서버 처리
    → HTTP 응답
    → HTML/CSS/JavaScript 해석
    → 브라우저 렌더링

    웹개발은 이 흐름을 계속 확장해 나가는 과정이라고 생각해도 좋습니다.

    프론트엔드 개발자는 브라우저 안에서 더 좋은 사용자 경험을 만들고, 백엔드 개발자는 서버에서 더 안정적이고 정확한 응답을 만들고, 인프라 영역은 이 요청과 응답이 안정적으로 오갈 수 있도록 도와줍니다.

    처음에는 모든 용어가 낯설 수 있습니다. 하지만 "브라우저가 요청하고 서버가 응답한다"는 큰 그림을 먼저 잡으면, 이후에 HTTP, API, 쿠키, 세션, CORS, 배포, 캐시 같은 개념들도 훨씬 쉽게 연결됩니다.


    함께 읽으면 좋은 글


    참고 자료

Designed by Tistory.