HTTP(Hyper Text Transfer Protocol)
는 Header(헤더)
와 Body(본문, payload, content)
로 구성되어 있다.
Header
는 기본적으로 key: value
꼴이며, 보통 ascii
코드에 속한 언어를 주로 사용한다. 그 외 언어는 허용하지 않지만, 불가피하게 사용해야 한다면 인코딩해서 사용하는 방법이 있다. 예를 들어, '헬로 월드'를 encodeURIComponent("헬로 월드")
로 인코딩하면 %ED%97%AC%EB%A1%9C%20%EC%9B%94%EB%93%9C
이라는 문자열이 생성되고, 이는 브라우저가 해석할 수 있어 사용 가능하다.
참고로, Body
를 표현하는 용어 중 content
는 구스펙(RFC 2616) 용어이고, payload
는 최신 스펙(RFC 7231) 용어이다. 공식 문서를 참고한다면 스펙에 따라 용어가 다름을 유념한다.
클라이언트가 어떤 리소스를 원하는지 명시한 것을 컨텐츠 협상(Content Negotiation)
이라고 한다. 여기에는 클라이언트 주도 협상과 서버 주도 협상이 존재한다.
서버가 제시한 리소스 종류 중 하나를 클라이언트가 선택해 요청을 보내는 것인데, 요청을 2번 보내는 까닭에 자원 낭비가 생겨 잘 사용하지 않는다.
클라이언트가 원하는 정보를 서버에게 나열하여 알려주면, 서버는 그에 맞는 리소스를 담아 응답한다. 이를 담당하는 헤더를 살펴 보자. 인용한 헤더 정보는 MDN - 콘텐츠 협상의 헤더이다.
Accept
: 원하는 리소스를 MIME Type
으로 적어 서버에게 알려주는 헤더이다. q
를 통해 중요도를 적어 우선순위를 정한다. 중요도는 1~0 사이의 숫자로 표현한다. MDN - Accept
MIME Type
은 대분류/확장자꼴이며 컨텐츠가 어떤 형식으로 되어 있는지 서버에게 알려주는 역할을 한다.
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
*/*
는 모든 MIME
을 의미한다. 즉, q=0.9
에 해당하는 타입이 없으면 다른 모든 타입을 받겠다는 것과 마찬가지라고 볼 수 있다.
Accept-Language
: 문서의 언어를 요청한다. MDN - Accept-Language
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6,zh-TW;q=0.5,zh;q=0.4
언어 코드는 ISO 639-2 Language Code List에서 찾을 수 있다.
Accept-Encoding
: 압축 종류를 요청한다. MDN - Accept-Encoding
Accept-Encoding: gzip, deflate, br
Accept-Charset
: 문자열 인코딩 방식을 요청한다. 하지만 지금은 폐기되었다. 이유는 현재 UTF-8
이 잘 지원되고 있고 압도적으로 선호되기 때문이며, 개인정보 보호를 위함이라고 한다.
위의 요청 헤더들은 몇몇 응답 헤더와 연결지어 진다.
Accept- | Content- | Example |
---|---|---|
Accept | Content-Type | Content-Type: text/html |
Accept-Language | Content-Language | Content-Language: en-US |
Accept-Encoding | Content-Encoding | Content-Encoding: gzip |
MDN - Content-Type
MDN - Content-Language
MDN - Content-Encoding
HTTP/1.0을 위해 존재했던 헤더로, HTTP/1.1에서는 기본값으로 설정되어 있다. 목적은 3way handshake
유지를 위해서 였으며, 초단위로 계산해 해당 시간 내에 다시 요청·응답이 오가면 연결 작업을 하지 않았다. Connection
과 연관이 있는데, HTTP/2에서는 무시된다.
MDN - Keep-Alive
서버에서 응답 데이터가 생성된 시간을 나타내며, 정확한 시간이 아닐 수도 있다. 서버가 시간을 조작했을 수도 있기 때문이다. 서버 시간을 확인하는 용도로 사용할 수도 있다.
메세지가 생성된 시간이지, 브라우저에 도착한 시간이 아니라는 점은 유념해야 한다. MDN - Date
Date: Wed, 21 Oct 2015 07:28:00 GMT
리소스를 안전하게 전송하기 위한 인코딩 형식을 지정한다. 특히, chunked
라는 값을 가지고 있다면 Content-Encoding
한 데이터를 일정 크기로 쪼개서 전송한다. MDN - Transfer-Encoding
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
7\r\n
Network\r\n
0\r\n
\r\n
서버에 요청 자격을 증명하는 자격을 보내는 역할이다. Bearer token
이나 Digest
등의 방식이 있지만, 일단 서버에서 보내달라고 요청하는 형식에 맞춰 세팅해야 한다. Basic
도 있지만 거의 사용하지 않는다고 한다. MDN - Authorization
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
서버에서 응답 가능한 메서드를 명시한다. 명시된 메서드가 아니라면 요청을 보낼 수 없다. MDN - Allow
Allow: GET, POST, HEAD
현재 페이지를 방문하기 이전 페이지가 어딘지 알려주는 역할이다. 유입 경로, 성과 측정 등에 사용할 수도 있겠지만, 개인 정보 보호 문제가 생길 수 있어 주의해야 한다. Referrer Policy
는 이러한 문제를 방지하는 정책이다. MDN - Referer
구글 검색으로 사이트를 방문한 까닭에 이렇게 나왔다.
Referer: https://www.google.com/
여기서 Referer
가 오타라는 점이 재미있다. 공식 문서 상에 오타로 등록되어 현재까지 이어져 오고 있다. 원래 철자는 Referrer
이다. 위키백과 - Referer가 된 이유 - HTTP 리퍼러 中
MDN HTTP 헤더
레퍼런스에 없는 헤더의 경우 커스텀 헤더일 가능성이 높다. 주로 X
를 접두사로 사용한다.
커스텀 헤더를 사용할 때는 기존 헤더명을 사용하는지 고려해야 한다. 의도치 않게 헤더를 조작할 수 있기 때문이다. 물론 기존 헤더명과 기능을 정확히 알고 의도적으로 덮어 쓰는 경우라면 상관없을 것이다.
X-Cache: hit
X-Cloud-Trace-Context: a7f9104d4f48c00f5bd242a1304218cb
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Goog-Generation: 1684889172510845
X-Goog-Hash: crc32c=W7tIVg==, md5=gnSc5MinRcnY4N38T0oSIA==
X-Goog-Meta-Goog-Reserved-File-Mtime: 1684887673