안녕하세요! 웹 개발의 기초가 되는 HTTP에 대해 더 깊이 알아보는 시간을 가져보겠습니다. 오늘은 HTTP 헤더의 다양한 종류와 역할, 웹 성능을 최적화하는 캐시, 사용자의 상태를 기억하는 쿠키, 그리고 사용자에게 최적의 콘텐츠를 제공하기 위한 콘텐츠 협상까지 자세히 살펴보겠습니다.
HTTP 메시지는 헤더(Header)와 본문(Body)으로 구성되며, 헤더에는 해당 요청 또는 응답에 대한 부가 정보가 담겨있습니다. 이 정보들은 클라이언트와 서버 간의 원활한 통신을 돕는 중요한 역할을 합니다. 헤더는 여러 필드들로 구성되며, 각 필드는 이름과 값을 가집니다.
클라이언트가 서버로 요청을 보낼 때 주로 사용되는 헤더들입니다.
Host
: 요청하는 서버의 도메인 이름과 포트 번호를 명시합니다. 예를 들어 Host: www.example.com
과 같이 사용됩니다. 포트 번호가 표준 포트(HTTP의 경우 80, HTTPS의 경우 443)가 아닐 경우 함께 포함될 수 있습니다 (예: Host: www.example.com:8080
).User-Agent
: 요청하는 클라이언트(예: 웹 브라우저, 모바일 앱)의 정보를 담습니다. 운영체제, 브라우저 종류 및 버전, 렌더링 엔진 등 다양한 정보를 포함할 수 있습니다. 서버는 이 User-Agent
정보를 보고 클라이언트의 접속 환경을 판단하여 최적화된 응답을 제공할 수 있습니다.User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
Referer
: 현재 요청을 보내게 된 이전 웹 페이지의 URL을 명시합니다. 예를 들어, 사용자가 https://en.wikipedia.org
페이지에 있는 링크를 클릭하여 현재 페이지로 이동했다면, Referer
헤더 값은 https://en.wikipedia.org
가 됩니다. 이를 통해 유입 경로 분석 등에 활용될 수 있습니다. ('Referrer'가 올바른 철자이지만, 역사적인 이유로 'Referer'로 사용됩니다.)Authorization
: 클라이언트의 인증 정보를 서버에 전달할 때 사용됩니다. 다양한 인증 방식이 있으며, 대표적으로 Basic
인증 방식이 있습니다.username:password
형태의 문자열을 Base64로 인코딩하여 인증 정보로 사용합니다.minchul:1234
→ (Base64 인코딩) → bWluY2h1bDoxMjM0
Authorization: Basic bWluY2h1bDoxMjM0
Basic
인증은 반드시 HTTPS와 함께 사용되어야 안전합니다.서버가 클라이언트로 응답을 보낼 때 주로 사용되는 헤더들입니다.
Server
: 응답을 생성한 웹 서버의 소프트웨어 관련 정보를 나타냅니다.Server: Apache/2.4.41 (Unix)
(Unix 운영체제에서 동작하는 아파치 HTTP 서버)Allow
: 해당 리소스에 대해 클라이언트에게 허용된 HTTP 메서드 목록을 알려주기 위해 사용됩니다.Allow: GET, HEAD, POST
Retry-After
: 서비스가 일시적으로 사용 불가능할 때 (예: 상태 코드 503 Service Unavailable
응답 시) 클라이언트에게 얼마 후에 다시 시도해야 하는지를 알려줍니다. 값은 구체적인 날짜/시간 또는 초 단위로 지정할 수 있습니다.Retry-After: Fri, 23 Aug 2024 09:00:00 GMT
(2024년 8월 23일 금요일 09시 이후에 사용 가능)Retry-After: 120
(120초 이후에 사용 가능)Location
: 클라이언트에게 요청한 자원이 다른 위치로 이동되었음을 알리거나(예: 301 Moved Permanently
, 302 Found
응답 시), POST 요청 후 새로운 리소스의 위치를 알려줄 때 사용됩니다. 브라우저는 이 헤더 값을 보고 해당 URL로 자동 리디렉션합니다.Location: /new-page.html
WWW-Authenticate
: 리소스에 접근하기 위해 필요한 인증 방식을 클라이언트에게 알릴 때 사용되며, 주로 상태 코드 401 Unauthorized
응답과 함께 전송됩니다.WWW-Authenticate: Basic realm="My Application"
(Basic 인증을 요구하며, 인증 영역(realm)의 이름은 "My Application"임을 알림)Authorization
& WWW-Authenticate
)401 Unauthorized
응답과 함께 WWW-Authenticate
헤더를 전송하여 필요한 인증 방식(예: Basic)을 알립니다.WWW-Authenticate
헤더에서 지정한 방식에 따라 인증 정보를 가공하여 (예: Base64 인코딩) Authorization
헤더에 담아 다시 요청합니다.Authorization
헤더의 인증 정보를 검증하고, 유효하면 요청된 리소스를 제공합니다.요청과 응답 양쪽 모두에서 사용될 수 있는 일반적인 헤더들입니다.
Date
: HTTP 메시지가 생성된 날짜와 시각 정보를 나타냅니다. (RFC 1123 형식)Date: Tue, 06 May 2025 12:00:00 GMT
Connection
: 현재의 전송이 완료된 후 네트워크 접속을 유지할지 말지를 제어합니다.Connection: keep-alive
(지속 연결을 희망)Connection: close
(연결 종료를 희망)Content-Length
: 메시지 본문(payload)의 길이를 바이트 단위로 나타냅니다.Content-Type
, Content-Language
, Content-Encoding
: 이들은 표현 헤더(Representation Headers)의 일종으로, 메시지 본문의 내용에 대한 구체적인 정보를 제공합니다.Content-Type
: 본문의 미디어 타입(MIME 타입)을 명시합니다.Content-Type: text/html; charset=utf-8
, Content-Type: application/json
, Content-Type: image/jpeg
Content-Language
: 본문이 표현하는 자연어를 명시합니다.Content-Language: ko-KR
, Content-Language: en-US
Content-Encoding
: 본문에 적용된 압축 또는 변환 방식을 명시합니다. 클라이언트는 이 정보를 바탕으로 본문을 올바르게 디코딩할 수 있습니다.Content-Encoding: gzip
, Content-Encoding: deflate
캐시는 불필요한 네트워크 트래픽을 줄이고, 웹 페이지 로딩 속도를 향상시키기 위해 정보의 사본을 임시로 저장하는 기술입니다. 한 번 받아온 데이터를 재사용함으로써 응답 지연을 방지하고 더 빠르게 데이터에 접근할 수 있게 해줍니다.
서버는 응답 헤더를 통해 캐시의 유효 기간을 설정할 수 있습니다. 예를 들어, Cache-Control
헤더의 max-age
지시자를 사용하거나 Expires
헤더를 사용하여 캐시가 얼마나 오랫동안 유효한지를 명시할 수 있습니다.
Cache-Control: max-age=1200
(1200초 동안 유효)으로 설정할 수 있습니다.캐시된 데이터가 여전히 유효한지(신선한지) 확인하는 과정입니다. 유효 기간이 지난 캐시는 원 서버에 변경 사항이 있는지 확인해야 합니다.
날짜를 이용한 검사 (If-Modified-Since):
클라이언트는 캐시된 리소스의 마지막 변경 날짜를 If-Modified-Since
요청 헤더에 담아 서버에 보냅니다.
If-Modified-Since: Fri, 23 Aug 2024 09:00:00 GMT
304 Not Modified
응답을 보내고, 클라이언트는 캐시된 버전을 사용합니다.200 OK
응답과 함께 새로운 리소스를 본문에 담아 보냅니다.엔티티 태그 (Entity Tag - Etag)를 이용한 검사 (If-None-Match):
Etag는 특정 버전의 리소스를 식별하는 고유한 문자열입니다. 서버는 리소스를 제공할 때 Etag
응답 헤더에 이 값을 포함시킵니다.
Etag: "abc"
If-None-Match
요청 헤더에 담아 서버에 보냅니다.If-None-Match: "abc"
304 Not Modified
응답을 보냅니다.200 OK
응답과 함께 새로운 리소스 및 새로운 Etag를 보냅니다.쿠키는 서버가 사용자의 웹 브라우저에 저장하는 작은 데이터 조각입니다. HTTP는 기본적으로 상태를 유지하지 않는(stateless) 프로토콜이기 때문에, 쿠키는 이러한 한계를 보완하여 사용자의 로그인 상태, 장바구니, 사이트 설정 등과 같은 정보를 클라이언트 측에 저장하고 재사용할 수 있도록 합니다.
Set-Cookie
응답 헤더를 통해 클라이언트에게 쿠키의 이름과 값, 그리고 만료일, 경로 등의 속성을 전달합니다.Set-Cookie: sessionId=38afes7a8; HttpOnly; Secure
Cookie
요청 헤더에 해당 쿠키들을 담아 자동으로 전송합니다.Cookie: sessionId=38afes7a8; anotherCookie=value
쿠키는 다양한 속성을 통해 동작을 제어할 수 있습니다.
Secure
: 이 속성이 설정된 쿠키는 HTTPS 프로토콜을 통해서만 전송됩니다. 암호화되지 않은 HTTP 연결에서는 전송되지 않아 중간자 공격으로부터 쿠키를 보호합니다.HttpOnly
: 이 속성이 설정된 쿠키는 JavaScript와 같은 클라이언트 측 스크립트를 통해 접근할 수 없습니다. document.cookie
등으로 쿠키를 읽거나 수정하는 것을 막아, XSS(Cross-Site Scripting) 공격을 통해 쿠키가 탈취되는 것을 방지하는 데 도움을 줍니다.콘텐츠 협상(Content Negotiation)은 클라이언트와 서버가 동일한 URL(URI)에 대해 여러 가지 버전의 리소스가 존재할 때, 클라이언트에게 가장 적합한 형태의 리소스를 제공하기 위한 메커니즘입니다. 예를 들어, 같은 콘텐츠라도 한국어 버전과 영어 버전이 있거나, HTML 형식과 JSON 형식이 있을 수 있습니다.
표현(Representation)은 서버와 클라이언트 간에 실제로 전송되는 자원의 특정 형태를 의미합니다. 이는 특정 언어, 미디어 타입, 문자 인코딩 등으로 구체화될 수 있습니다.
클라이언트는 요청 헤더(주로 Accept
, Accept-Language
, Accept-Encoding
등)를 사용하여 자신이 선호하는 표현 형식을 서버에 알립니다.
선호하는 언어: 클라이언트가 Accept-Language
헤더를 통해 선호하는 언어를 서버에 전달합니다.
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
선호하는 미디어 타입: 클라이언트가 Accept
헤더를 통해 선호하는 문서 타입을 서버에 전달합니다.
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
text/html
) 또는 XHTML 문서(application/xhtml+xml
)를 가장 선호한다. 그 다음으로는 XML 문서(application/xml
, q=0.9)를 선호하고, 그 외 이미지나 다른 모든 타입(*/*
, q=0.8)도 받을 수 있다.서버는 이러한 클라이언트의 선호도와 서버가 제공할 수 있는 리소스의 형태를 비교하여 가장 적절한 표현을 선택하고 응답합니다.
이렇게 HTTP 헤더, 캐시, 쿠키, 그리고 콘텐츠 협상에 대해 자세히 알아보았습니다. 웹의 동작 방식을 이해하는 데 도움이 되셨기를 바랍니다!
혹시 잘못된 내용이나 추가하고 싶은 의견이 있다면 댓글로 편하게 남겨주세요!