Загружаем каталог…
Загружаем каталог…
시작 이전 글에서는 TCP 연결 이후 TLS를 통해 브라우저와 서버가 안전하게 통신할 수 있는 환경을 만드는 과정까지 살펴봤다 지금까지의 흐름을 정리하면 다음과 같다 URL 입력 ↓ URL 해석 ↓ DNS 조회 ↓ IP 주소 획득 ↓ TCP 연결 ↓ TLS Handshake ↓ 안전한 통신 환경 구성 이제 브라우저와 서버는 데이터를 안전하게 주고받을 준비를 마쳤다 그렇다면 실제로 어떤 데이터를 주고받는 걸까? 브라우저와 서버에 웹 페이지를 요청한다는 것은 단순히 주소를 전달하는 것만을 의미하지 않는다 어떤 리소스를 원하는지 어떤 현태의 데이터를 받을 수 있는지 요청에 추가적인 정보가 필요한지 등을 함께 전달할 수 있다 서버 역시 요청에 대한 결과뿐만 아니라 요청이 성공했는지 어떤 종류의 데이터를 반환하는지 등의 정보를 함께 전달한다 이러한 요청과 응답의 형식을 정의하는 것이 HTTP다 이번 글에서는 브라우저가 서버에 보내는 HTTP Request와 서버가 반환하는 HTTP Response가 어떤 구조로 이루어져 있는지 살펴보려고 한다 HTTP란 무엇일까? HTTP는 HyperText Transfer Protocol의 약자로 클라이언트와 서버가 데이터를 주고받기 위한 애플리케이션 계층 프로토콜이다 HTTP는 기본적으로 요청과 응답을 중심으로 동작한다 Client | | HTTP Request |--------------> | | HTTP Response |<-------------- | Server 클라이언트가 서버에 요청을 보내면 서버는 요청을 처리한 뒹 그 결과를 응답으로 반환한다 이때 HTTP는 단순히 데이터를 주고받는다는 사실만 정의하는 것이 아니라 요청에 어떤 정보가 포함되어야 하는지도 정의한다 예를 들어 클라이언트는 다음과 같은 정보를 전달할 수 있다 어떤 작업을 요청하는가 어떤 리소스를 요청하는가 어떤 종류의 응답을 받을 수 있는가 요청과 함께 전달할 데이터가 있는가 서버 역시 다음과 같은 정보를 반환할 수 있다 요청이 성공했는가 어떤 종류의 데이터를 반환하는가 응답을 캐싱해도 되는가 실제 응답 데이터는 무엇인가 그렇다면 실제 HTTP 메시지는 어떤 모습일까? HTTP Request는 어떻게 구성되어 있을까? 브라우저가 다음 주소에 접속한다고 생각해보자 https://example.com/posts/1 DNS와 연결 과정을 거쳐 서버와 통신할 준비를 마쳐다면 브라우저는 해당 리소스를 요청한다 HTTP/1.1 형식으로 표현하면 다음과 같다 GET /posts/1 HTTP/1.1 Host: example.com Accept: text/html 이 요청을 크게 나누면 다음과 같은 구조다 Request Line ↓ Request Headers ↓ 빈 줄 ↓ Request Body (선택) 각 부분이 어떤 역할을 하는지 살펴보자 여기서 사용하는 예시는 HTTP 메시지의 구조를 이해하기 위한 HTTP/1.1 형식이며 HTTP/2와 HTTP/3에서는 실제 전송 형식이 달라진다 Request Line HTTP/1.1 요청의 첫 번째 줄을 Request Line이라고 한다 GET /posts/1 HTTP/1.1 이를 나누면 다음과 같다 GET -> Method /posts/1 -> Request Target HTTP/1.1 -> HTTP Version 각각의 의미를 하나씩 살펴보자 Method Method는 클라이언트가 서버에 어떤 작업을 요청하는지 나타낸다 대표적인 HTTP Method는 다음과 같다 GET -> 리소스 조회 POST -> 데이터를 제출하거나 처리를 요청 PUT -> 리소스를 생성하거나 전체 교체 PATCH -> 리소스의 일부 벼경 DELETE -> 리소스 삭제 요청 예를 들어 게시글을 조회하려는 경우에는 GET을 사용할 수 있다 반대로 새로운 게시글을 생성하려는 경우에는 POST를 사용할 수 있다 여기서 중요한 것은 Method 자체가 실제 서버의 동작을 수행하는 것은 아니라는 점이다 Method는 요청의 의미를 나타내며 서버는 이를 바탕으로 어떤 작업을 수행하지 결정한다 또한 PUT과 PATCH의 의미는 구분되지만 실제 리소스 변경 방식은 서버의 API 설계에 따라 달라질 수 있다 Request Target 다음은 요청 대상이다 GET /posts/1 HTTP/1.1 여기서 /posts/1 은 클라이언트가 요청하려는 리소스를 가리킨다 이전 글에서 살펴봤던 URL과 연결해보면 다음과 같다 https://example.com/posts/1 ↓ /posts/1 앞서 URL을 해석하면서 서버의 위치를 찾았다면 이제는 해당 서버에 어떤 리소스를 원하는지 전달하는 것이다 Query String이 포함된 경우에는 다음과 같이 전달할 수 있다 https://example.com/posts?sort=latest GET /posts?sort=latest HTTP/1.1 반면 URL Fragment는 HTTP 요청 대상에 포함되지 않는다 https://example.com/posts/1#comment 이 경우 일반적인 HTTP 요청에는 다음과 같이 전달된다 GET /posts/1 HTTP/1.1 #comment 는 브라우저가 문서 내부의 특정 위치 등을 처리하기 위한 정보이기 때문에 서버에 전달하는 요청 대상에서는 제외된다 Request Headers Request Line 다음에는 요청에 대한 추가 정보를 전달하는 Header가 존재한다 예를 들어 다음과 같은 요청이 있다고 해보자 GET /posts/1 HTTP/1.1 Host: example.com Accept: text/html Accept-Language: ko 각 Header는 이름과 값으로 구성된다 Header Name: Header Value Host Host: example.com Host는 클라이언트가 어떤 호스트를 대상으로 요청하는지 나타낸다 앞서 DNS를 통해 IP 주소를 알아냈는데 왜 다시 도메인 정보를 전달할까? 하나의 IP 주소에서 여러 웹 사이트를 제공할 수도 있기 때문이다 example.com ──┐ ├── 동일한 IP 주소 other.com ────┘ 서버는 Host 정보를 이용해 어떤 호스트를 대상으로 요청하는지 구분할 수 있다 즉 IP 주소가 네트워크에서 목적지를 찾아가는 데 사용된다면 Host는 HTTP 수준에서 요청 대상을 식별하는 데 사용된다 Accept Accept: text/html Accept는 클라이언트가 어떤 종류의 응답 데이터를 받아들일 수 있는지 나타낸다 예를 들어 HTML 문서를 원하는 경우 text/html 을 전달할 수 있닫 JSON 응답을 받을 수 있다는 의미로 다음과 같이 전달할 수도 있다 Accept: application/json 다만 Accept에서 특정 형식을 지정했다고 해서 반드시 서버가 그 형식으로 응답해야 하는 것은 아니다 서버가 지원하는 응답 형식과 요청에 따라 실제 결과가 결정된다 Cookie 브라우저가 서버에 쿠키를 전달해야 하는 상황이라면 다음과 같은 Header가 포함될 수 있다 Cookie: session=abc123 쿠키는 서버와 클라이언트 사이에서 상태를 유지하는 데 활용될 수 있다 예를 들어 로그인 이후 발급된 세션 식별자를 쿠키에 저장했다면 이후 요청에서 해당 값을 서버에 전달할 수 있다 Browser ↓ Cookie: session=abc123 ↓ Server ↓ 세션 정보 확인 모든 요청에 Cookie가 포함되는 것은 아니며 브라우저는 쿠키의 도메인, 경로, 보안 속성 등에 따라 전송 여부를 결정한다 Request Body HTTP 요청에는 Header 외에도 Body가 포함될 수 있다 Body는 서버에 전달하려는 실제 데이터를 담는 영역이다 예를 들어 게시글을 생성하는 요청을 생각해보자 POST /posts HTTP/1.1 Host: example.com Content-Type: application/json { "title": "HTTP", "content": "HTTP Request" } 이 요청에서 Body에 해당하는 부분은 다음과 같다 { "title": "HTTP", "content": "HTTP Request" } 여기서 Content-Type 은 Body에 포함된 데이터의 형식을 나타낸다 Content-Type: application/json 즉 서버는 해당 Body가 JSON 형식이라는 사실을 알 수 있다 HTML Form 데이터를 전송하거나 파일을 업로드하는 경우에는 다른 형식이 사용될 수도 있다 여기서 Request Header, Request Body의 역할을 구분할 수 있다 Request Header → 요청에 대한 부가 정보 Request Body → 실제로 전달하려는 데이터 참고로 모든 HTTP 요청에 Body가 필요한 것은 아니다 앞서 살펴본 GET 요청은 일반적으로 Body 없이 요청 대상을 지정하는 방식으로 사용된다 서버는 HTTP Request를 받으면 무엇을 할까? 지금까지 클라이언트가 어떤 형태로 요청을 보내는지 살펴봤다 그렇다면 요청이 서버에 도착하면 어떻게 될까? 아주 단순하게 표현하면 다음과 같다 HTTP Request 수신 ↓ Method 확인 ↓ 요청 대상 확인 ↓ Header 및 필요한 Body 확인 ↓ 요청 처리 ↓ HTTP Response 생성 예를 들어 서버가 다음 요청을 받았다고 해보자 GET /posts/1 HTTP/1.1 Host: example.com 서버는 해당 요청을 해석한 뒤 필요한 작업을 수행한다 게시글을 조회하는 요청이라면 저장된 데이터를 조회할 수도 있고 미리 준비된 문서를 반환할 수도 있다 이처럼 실제 요청을 처리하는 과정은 서버의 구현에 따라 달라진다 하지만 요청 처리 이후 결과를 HTTP Response도 반환한다는 기본 구조는 동일하다 HTTP Response는 어떻게 구성되어 있을까? 서버가 요청을 처리한 뒤 반환하는 HTTP Response도 일정한 구조를 가진다 예를 들어 HTML 문서를 요청한 경우 다음과 같은 응답이 반환될 수 있다 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 <!DOCTYPE html> <html lang="ko"> <head> <title>Example</title> </head> <body> <h1>Hello</h1> </body> </html> 응답 역시 크게 세 부분으로 나눌 수 있다 Status Line ↓ Response Headers ↓ 빈 줄 ↓ Response Body (선택) 요청과 구조가 비슷하지만 각각의 역할은 다르다 Status Line HTTP/1.1 응답의 첫 번째 줄을 Status Line이라고 한다 HTTP/1.1 200 OK 이를 나누면 다음과 같다 HTTP/1.1 -> HTTP Version 200 -> Status Code OK -> Reason Phrase 여기서 중요한 것은 Status Code다 Status Code는 서버가 요청을 어떻게 처리했는지 나타내는 숫자 코드다 대표적인 상태 코드의 범위는 다음과 같다 1xx -> 정보성 응답 2xx -> 성공 3xx -> 리다이렉션 관련 응답 4xx -> 클라이언트 오류 5xx -> 서버 오류 각 범위 안에도 여러 상태 코드가 존재한다 예를 들어 다음과 같다 200 OK → 요청 성공 201 Created → 리소스 생성 성공 301 Moved Permanently → 리소스가 영구적으로 이동 304 Not Modified → 조건부 요청에 대해 리소스가 변경되지 않음 400 Bad Request → 잘못된 요청 401 Unauthorized → 유효한 인증 정보가 필요함 403 Forbidden → 요청한 작업이 허용되지 않음 404 Not Found → 요청한 리소스를 찾을 수 없음 500 Internal Server Error → 서버 내부 오류 브라우저는 이러한 상태 코드를 통해 요청 결과를 판단할 수 있다 예를 들어 리다이렉션 응답을 받으면 응답에 포함된 위치 정보를 바탕으로 다른 주소에 다시 요청할 수 있다 다만 모든 3xx 응답이 동일한 방식으로 동작하는 것은 아니며 304처럼 기존에 저장된 응답을 재사용하기 위한 상태 코드도 존재한다 Response Headers 서버는 Status Line 다음에 응답에 대한 추가 정보를 Header에 담아 전달한다 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Cache-Control: max-age=3600 여기에서 몇 가지 Header를 살펴보자 Content-Type Content-Type: text/html; charse=utf-8 Content-Type 은 응답 Body의 데이터 형식을 나타낸다 브라우저는 이를 통해 응답으로 전달받은 데이터가 어떤 종류인지 판단할 수 있다 예를 들어 HTML 문서라면 다음과 같다 Content-Type: text/html JSON 데이터라면 다음과 같다 Content-Type: application/json 이미지나 CSS, 자바스크립트 등의 리소스 역시 각각의 데이터 형식을 가진다 따라서 브라우저는 모든 응답을 동일한 방식으로 처리하지 않는다 응답의 종류와 사용 목적에 따라 이후 과정이 달라진다 Cache-Control Cache-Control: max-age=3600 Cache-Control 은 캐시가 응답을 어떻게 저장하고 재사용할 수 있는지에 대한 지시를 전달한다 예를 들어 max-age=3600 은 응답을 저장한 캐시가 정해진 조건 아래에서 최대 3600초 동안 해당 응답을 최신 상태로 간주할 수 있다는 의미다 이전 글에서 DNS 캐시를 살펴봤다면 이번에는 HTTP 응답에서 캐시 정책이 존재한다는 점을 확인할 수 있다 HTTP Request ↓ Cache 확인 ↓ 사용 가능한 응답이 있음 ↓ 저장된 응답 재사용 캐시 정책에 따라 브라우저가 서버에 다시 요청하지 않고 저장된 응답을 사용할 수도 있다 반대로 저장된 응답을 재검증하기 위해 서버에서 조건부 요청을 보낼 수도 있다 즉 HTTP Header는 단순히 데이터의 형식을 설명하는 것뿐만 아니라 이후 네트워크 통신 방식에도 영향을 줄 수 있다 Set-Cookie Set-Cookie: session=abc123; Path=/; Secure; HttpOnly 서버는 Set-Cookie Header를 통해 브라우저에 쿠키를 저장하도록 요청할 수 있다 이후 브라우저는 쿠키의 속성과 요청 조건에 따라 저장된 값을 다시 서버에 전달할 수 있다 Server ↓ Set-Cookie ↓ Browser ↓ Cookie 저장 ↓ 다음 요청에서 조건에 맞으면 Cookie 전달 ↓ Server 여기서 Request의 Cookie와 Response의 Set-Cookie 는 서로 다른 역할이다 Cookie → 클라이언트가 서버에 쿠키 전달 Set-Cookie → 서버가 클라이언트에 쿠키 설정 요청 Response Body Response Body에는 서버가 실제로 반환하려는 데이터가 들어간다 앞서 HTML 문서를 요청했다면 다음과 같은 응답을 받을 수 있다 HTTP/1.1 200 OK Content-Type: text/html <!DOCTYPE html> <html> <body> <h1>Hello</h1> </body> </html> 여기서 HTML 문서가 Response Body에 해당한다 반면 JSON 데이터를 요청했다면 다음과 같은 응답을 받을 수도 있다 HTTP/1.1 200 OK Content-Type: application/json { "id": 1, "title": "HTTP" } HTTP Request의 Body에는 HTML 뿐만 아니라 JSON, 이미지, CSS, 자바스크립트 등 다양한 데이터가 들어갈 수 있다 또한 모든 응답에 Body가 포함되는 것은 아니다 예를 들어 204 No Content 나 304 Not Modified 와 같은 응답에는 메시지 Body가 포함되지 않는다 HTML 응답을 받으면 바로 화면이 만들어질까? 이제 HTTP 요청과 응답을 하나의 흐름으로 연결해보자 브라우저가 다음 URL에 접속했다고 해보자 https://example.com HTTP 요청이 서버에 전달된다 GET / HTTP/1.1 Host: example.com Accept: text/html 서버는 요청을 처리한 뒤 HTML 문서를 응답으로 반환한다 HTTP/1.1 200 OK Content-Type: text/html <!DOCTYPE html> <html> <body> <h1>Hello</h1> </body> </html> 그러면 브라우저가 응답을 받게 된다 Browser ↓ HTTP Request ↓ Server ↓ HTTP Response ↓ Browser 하지만 HTML 데이터를 받았다는 사실만으로 화면이 완성되는 것은 아니다 브라우저는 응답으로 전달받은 HTML을 해석하고 문서 구조를 만들어야 한다 또한 HTML을 해석하는 과정에서 CSS나 자바스크립트, 이미지 같은 다른 리소스를 발견하면 추가적인 HTTP 요청이 발생할 수 있다 HTML 응답 수신 ↓ HTML 해석 ↓ CSS / JavaScript / Image 발견 ↓ 추가 HTTP Request ↓ 추가 HTTP Response ↓ 브라우저에서 리소스 처리 따라서 하나의 웹 페이지를 화면에 표시하기 위해 여러 번의 HTTP 요청과 응답이 발생할 수 있다 물론 이때마다 DNS 조회나 TCP 연결, TLS Handshake를 처음부터 반복해야 하는 것은 아니다 기존 연결을 재사용할 수 있다면 여러 HTTP 요청을 같은 연결을 통해 처리할 수도 있다 HTTP/2와 HTTP/3에서도 같은 구조일까? 지금까지 살펴본 HTTP 메시지는 HTTP/1.1의 형식을 기준으로 설명했다 하지만 이전 글에서 살펴봤던 것처럼 HTTP에는 여러 버전이 존재한다 HTTP/1.1 ↓ TCP HTTP/2 ↓ TCP HTTP/3 ↓ QUIC ↓ UDP HTTP/2와 HTTP/3에서는 메시지를 실제 네트워크에 전달하는 방식이 HTTP/1.1과 다르다 예를 들어 HTTP/2와 HTTP/3는 메시지를 바이너리 프레임 등의 형태로 전송하며 HTTP/1.1처럼 요청 첫 줄을 텍스트로 그대로 전달하지 않는다 하지만 HTTP Method, Header, Status Code와 같은 핵심적인 의미는 유지된다 즉 HTTP 버전이 바뀌더라도 클라이언트가 요청을 보내고 서버가 응답을 반환한다는 기본 구조는 동일하다 이번 글에서는 HTTP 메시지가 어떤 정보를 주고받는지 이해하는것이 목적이므로 각 버전의 세부 전송 방식은 별도로 다루지 않으려고 한다 이번 글에서 살펴본 흐름 이번 글에서는 브라우저와 서버가 주고받는 HTTP Request와 HTTP Response의 구조를 살펴봤다 HTTP Request에는 다음과 같은 정보가 포함될 수 있다 HTTP Request │ ├─ Method │ → 어떤 작업을 요청하는가 │ ├─ Request Target │ → 어떤 리소스를 요청하는가 │ ├─ Headers │ → 요청에 대한 추가 정보 │ └─ Body → 서버에 전달할 데이터 서버는 요청을 처리한 뒤 HTTP Response를 반환한다 HTTP Response │ ├─ Status Code │ → 요청을 어떻게 처리했는가 │ ├─ Headers │ → 응답에 대한 추가 정보 │ └─ Body → 실제로 반환하는 데이터 지금까지의 전체 흐름도 다음 단계까지 도달했다 URL 입력 ↓ DNS 조회 ↓ IP 주소 획득 ↓ TCP 연결 ↓ TLS Handshake ↓ HTTP Request ↓ Server ↓ HTTP Response ↓ Browser 이제 브라우저가 어떤 요청을 보내고 서버가 어떤 형태로 응답하는지 알게 되었다 하지만 아직 요청과 응답 데이터가 실제 네트워크를 통해 어떻게 이동하는지는 자세히 살펴보지 않았다 다음 글에서는 HTTP 메시지가 네트워크를 통해 이동하는 과정에서 등장하는 패킷과 IP, 라우터 등의 역할을 살펴보려고 한다 HTTP 메시지 ↓ 네트워크를 통한 데이터 전송 ↓ 서버
То, что RADAR обнаружил и классифицировал для этой возможности. Это опубликованный источником текст, а не подтверждение, что предложение ещё действует.
브라우저와 서버는 어떤 메시지를 주고받을까?. 시작 이전 글에서는 TCP 연결 이후 TLS를 통해 브라우저와 서버가 안전하게 통신할 수 있는 환경을 만드는 과정까지 살펴봤다 지금까지의 흐름을 정리하면 다음과 같다 URL 입력 ↓ URL 해석 ↓ DNS 조회 ↓ IP 주소 획득 ↓ TCP 연결 ↓ TLS Handshake ↓ 안전한 통신 환경 구성 이제 브라우저와 서버는 데이터를 안전하게 주고받을 준비를 마쳤다 그렇다면 실제로 어떤 데이터를 주고받는 걸까? 브라우저와 서버에 웹 페이지를 요청한다는 것은 단순히 주소를 전달하는 것만을 의미하지 않는다 어떤 리소스를 원하는지 어떤 현태의 데이터를 받을 수 있는지 요청에 추가적인 정보가 필요한지 등을 함께 전달할 수 있다 서버 역시 요청에 대한 결과뿐만 아니라…
Открыть источник