
자. 이번에도 새로운 주제를 들고 돌아와 보았다.
이번에는 'HTTP'에 대해서 알아보려고 한다!
웹 사이트를 사용할 때마다 볼 수 있는 HTTP이지만...
이에 대해서 제대로 알고 있는 것 같진 않아서 'HTTP'라는 주제를 들고 오게 되었다.
그럼 바로 알아보도록 하자!
HTTP
HTTP(Hyper Text Transfer Protocol)란?
HTTP란 서버와 클라이언트가 서로 데이터를 주고받기 위해 사용되는 통신 규약을 의미한다.
HTTP는 웹 문서 간에 링크를 통해 연결할 수 있는 프로토콜을 의미하며, 문서뿐만 아니라 HTML, TEXT, IMAGE, 음성, 영상, 파일 JSON, XML(API) 등등 거의 모든 형태의 데이터 전송이 가능한 프로토콜이다.
현재 웹 사이트에서 서버 간에 데이터를 주고받을 때 대부분 HTTP 프로토콜을 사용해서 통신하고 있다.
우리가 흔히 볼 수 있는 네이버를 예로 들어보면...
네이버의 주소는 http://www.naver.com이다.
여기서 보이는 'http'라는 부분이 바로! 네이버라는 웹 사이트가 HTTP 통신 규약대로 데이터 정보 등의 교환을 처리하고 있다는 것을 의미하는 것이다.
HTTP의 발전

HTTP는 1991년부터 다양한 발전을 거쳐 지금 우리가 쓰는 형태의 HTTP로 발전한 것인데...
각 버전별로 사용 가능한 메서드가 다르기도 하고 여러 버전을 거듭하면서 HTTP의 단점을 극복한 버전도 있다!
그럼 각 버전에 대해서는 아래에서 더 알아보도록 하자...
① HTTP/0.9 (1991년)
정적 웹페이지 전송에만 적합했던 초기 버전
- GET 메서드만 지원함
- HTTP 헤더 없음
- HTML 형식만 전송 가능
"전체적인 기능이 부족하고 확장성이 없던 버전"
② HTTP/1.0 (1996년)
구조는 갖췄지만, 확장성과 성능 측면에서 한계가 있던 버전
- 메서드, 헤더, 상태코드 개념 추가
- 요청 헤더 : HTTP 버전 추가
- 응답 헤더 : 상태코드와 content-type이 생겨 HTML 파일 외 다른 타입의 파일도 전송 가능
- 단기커넥션 : connection 하나당 하나의 요청, 하나의 응답만 처리 가능
- 'Connection: keep-alive'를 명시적으로 설정하여 연결이 종료되지 않도록 지정 가능
"매 요청마다 새로운 연결이 필요한 구조로, 성능 저하 및 서버 부하가 심했던 버전"
③ HTTP/1.1 (1997년)
우리가 쓰는 대부분의 HTTP 기능이 완성된 버전
- 현재 가장 많이 사용하며, 대부분의 기능이 추가된 버전
- Persistent connection : 지정한 timeout 동안 연속적인 요청 사이에 커넥션을 닫지 않는 것
- 'Connection: keep-alive'를 명시적으로 설정해야 했던 HTTP/1.0 버전과는 달리 기본적으로 설정되어 있음
- Pipelining : 하나의 커넥션에서 응답을 기다리지 않고 순차적인 여러 요청을 연속적으로 보내 그 순서에 맞춰 응답을 받는 방식으로 지연 시간을 줄이는 방식
- 그러나 Head Of Line Blocking와 같은 문제점 발생 가능
- Head Of Line Blocking : 우선순위로 들어온 요청의 응답 시간이 길어지면 후 순위에 있는 요청의 응답 시간도 길어지는 것
"요청 순서에 따라 응답이 지연되는 Head-of-Line Blocking 문제가 발생했던 버전"
④ HTTP/2.0 (2015년)
HTTP/1.1의 연결 순서 지연 문제를 획기적으로 개선한 버전
- HTTP 1.1의 성능을 개선 및 확장한 버전
- 바이너리 프레이밍 계층 사용한 메시지 전송 방식으로 변화
- 바이너리 프레이밍 계층:
- 파싱 및 전송속도의 증가
- 오류 발생 가능성의 저하
- 'Connection: keep-alive' 즉, 지속 연결 방식을 멀티플렉싱 방식으로 변경하여 더욱 발전된 방식으로 서버 통신을 진행
"TCP 기반으로 인해 패킷 손실 시 연결 전체 지연 문제(HOL Blocking)가 완전히 해결되지 않았던 버전"
⑤ HTTP/3.0 (2019년 ~ 진행중)
빠른 연결, 지연 최소화, 스트리밍 환경 등 차세대 웹 요구에 대응할 수 있도록 발전한 버전
- TCP 대신에 UDP를 이용한 QUIC 프로토콜 사용
- UDP 기반의 QUIC 프로코콜 바탕으로 제작
- 기존 TCP의 고질적인 지연시간(RTT)을 해결
"UDP 기반 QUIC이 상대적으로 새로운 기술이어서 완전한 보급과 안정성 확보가 진행 중인 버전"
HTTP의 통신 방식

HTTP 통신 방식은 클라이언트(Front-End)와 서버(Back-End)로 나뉜 구조로 진행된다.
클라이언트가 요청을 보내면 서버가 응답하는 방식으로 진행되는 것이다!
쉽게 풀어서 설명하자면, 클라이언트는 HTTP 메시지를 만들어 보내고, 서버에서 요청에 대한 응답이 올 때까지 기다린다.
그리고 서버는 요청에 대한 결과를 만들어서 응답을 클라이언트에게 보내는 방식으로 HTTP 통신이 진행되는 것이다.
그럼 왜...? 굳이...? 클라이언트와 서버로 나누어서 통신을 진행하는 걸까?
바로. 각자의 역할에 집중할 수 있기 때문이다.
클라이언트 즉, 프론트엔드에서는 복잡한 비즈니스 로직이나 데이터 관리에 대하여 크게 관여하지 않아도 되며, UI를 구성하는 데에 집중할 수 있게 된다.
이 말은 즉 서버를 관리하는 백엔드에서는 복잡한 비즈니스 로직이나 데이터를 다루는데만 집중하면 된다는 말이다.
만약 사용자 수가 급증하여 트래픽이 폭주한다면, 백엔드는 클라이언트 측면은 고려하지 않고 서버만 개선하면 된다는 것이다.
즉, 클라이언트와 서버를 독립적으로 구분한다는 것은 각자의 책임을 나눠 해당 책임에만 집중할 수 있도록 하며, 클라이언트와 서버 양쪽이 각각 독립적으로 고도화할 수 있다는 것을 의미한다.
HTTP의 특징
비연결성
HTTP는 요청과 응답이 끝나면 연결을 끊어 클라이언트와 서버가 지속적으로 연결된 상태를 유지하지 않도록 한다.
한 가지 예를 들어보자면...
어떤 사용자가 웹 페이지를 열었을 때, 서버는 HTML을 응답하고 곧바로 연결을 끊는다.
그리고 사용자의 브라우저는 HTML 내부의 이미지, JS, CSS 파일들을 다시 새로운 연결을 만들어 하나하나 요청을 진행한다.
이런 것처럼... HTTP는 매 요청마다 새로운 TCP 연결을 생성하고, 응답 후에는 즉시 연결을 종료한다.
딱 여기까지의 설명만 들으면, 굉장히 번거로운 방법이라는 생각을 할 수도 있지만, 이로 인해 얻는 장점도 존재한다!
1. 서버 자원 효율적 사용
연결을 계속 유지하면 서버의 메모리, 스레드, 포트 등의 자원이 고정적으로 소모된다.
하지만 비연결 방식은 필요할 때만 연결하고 응답이 끝나면 바로 종료하기 때문에 수천, 수만 명의 사용자를 동시에 처리하는 데 매우 유리하다.
2. 동시 접속 처리에 유리
연결을 유지하지 않기 때문에, 서버는 적은 연결 자원으로 더 많은 요청을 순차적으로 처리할 수 있다.
예를 들어, 검색창에 검색어를 입력한 뒤 결과를 기다리는 동안 서버는 그 연결을 계속 점유하지 않으므로 다른 사용자의 요청을 빠르게 처리할 수 있게 된다.
그렇다면... 단점은 없을까?
1. 연결 설정에 따른 오버헤드 발생
HTTP는 TCP 기반이기 때문에 매 연결마다 3-way handshake 과정이 반복된다. 요청할 때마다 연결을 새로 생성하는 방식은 응답 속도 지연이나 네트워크 비용 증가로 이어질 수 있다.
2. 많은 리소스를 요청할 경우 비효율
웹 페이지는 일반적으로 수많은 이미지, CSS, JS 파일을 포함한다. 만약 이 모든 리소스를 개별 연결로 요청한다면, 연결-요청-응답-종료의 반복으로 인해 성능 저하가 발생할 수 있다.
이러한 단점이 존재하긴 하지만...
똑똑한 사람들이 만들어낸 HTTP인 만큼, 이러한 단점을 해결하기 위한 방안을 만들어냈는데...
그것이 바로 지속 연결(Persistent Connection)이다!
HTTP/1.1부터는 'Connection: keep-alive'를 통해 하나의 연결을 유지하면서 여러 리소스를 연속적으로 주고받는 방식을 지원하고 있다.
뿐만 아니라 HTTP/2, HTTP/3에서는 한 연결에서 동시에 여러 요청을 처리하는 방식까지 도입하여 비효율적인 방식을 효율적인 방식으로 보완해나가고 있다고 한다.
무상태성

HTTP는 이전 요청과 다음 요청 사이의 상태를 유지하지 않기 때문에 서버는 클라이언트의 이전 요청 정보를 기억하지 않는다.
한 가지 예를 들어보자면...
어떠한 기능 사용 이전에 사용자가 로그인했더라도 서버는 다음 요청에서 로그인 상태를 기억하지 않는다.
즉, 로그인 여부를 판별하기 위해 사용자는 매 요청마다 인증 정보(토큰 등)를 함께 보내야 한다.
딱 여기까지의 설명만 들으면 굉장히 귀찮은 특징이라고 생각할 수 있지만, 이로 인해 얻는 장점은 존재한다.
1. 서버 확장에 유리
무상태의 환경에서는 각 요청이 독립적이기 때문에 어떤 서버가 처리해도 상관이 없다.
이 말은 즉, 요청 간의 상태 공유가 필요 없으므로 서버 간 부하 분산에도 유용하다는 이점을 얻을 수 있다.
2. 서버 구조의 단순화
서버는 각 요청을 그 자체만으로 판단하고 응답할 수 있다.
따라서 복잡한 세션 저장소, 상태 관리 로직이 필요하지 않다.
원래 장점이 존재하면 단점도 존재하는 법이다. 그렇다면 단점은 무엇일까?
1. 데이터 사용량 및 메모리 사용량 증가
아까도 말했듯이 매 요청마다 필요한 모든 정보(상태)를 클라이언트가 함께 전송해야 한다.
이 말은 즉, 요청이 늘어날수록 데이터의 사용량과 메모리 사용량이 늘어난다는 것을 의미한다.
2. 로그인 유지 등을 위해 별도의 수단 필요
서버는 상태 정보를 기억하지 않기 때문에 사용자의 로그인 정보를 유지하기 위해 쿠키, 세션, JWT 등의 수단이 필요하다.
HTTP 메시지 구조

HTTP 메시지는 기본적으로 위에서부터 차례대로 시작 라인(Start Line), 헤더(Header), 공백 라인(Empty Line), 바디(Message Body)로 구성된다.
공백 라인의 경우, HTTP 메시지 값 구분을 위한 라인으로, 단순히 보기 편하게 넣는 것뿐만 아니라 보낼 메시지 바디가 없을 때 공북만 넣고 끝내는 형식으로 사용된다.
바디의 경우, HTTP 요청 종류에 따라 포함될 때도 있고 아닐 때도 있다.
전체적인 구조는 위와 같지만...
HTTP 요청 메시지냐 응답 메시지냐에 따라 안의 내용의 차이가 생긴다.
이는 아래에서 예시를 통해 더 자세히 다뤄보겠다!
HTTP 요청 메시지

- 시작 라인(Start Line)
- Method : GET / POST / PUT / DELTE 등의 HTTP 메서드 영역
- URL : 요청 대상 경로 표시
- Version : 사용된 http 버전
- 헤더(Header)
- Headers : HTTP 전송에 필요한 모든 부가 정보 (인증, 브라우저 정보, 서버 정보, 캐시 등등)
- 공백 라인(Empty Line) : 헤더와 바디를 구분하기 위한 라인
- 바디(Message Body)
- Message Body : 실제 전송할 데이터 (HTML 문서, 이미지, 영상, JSON 등)
HTTP 응답 메시지

- 시작 라인(Start Line)
- Version : 사용된 http 버전
- Status Code : 클라이언트가 보낸 요청에 대한 응답 상태 코드
- Status Message : Status Code에 대한 결과를 글로 표현한 것
- 헤더(Header)
- Headers : HTTP 전송에 필요한 모든 부가 정보 (인증, 브라우저 정보, 서버 정보, 캐시 등등)
- 공백 라인(Empty Line) : 헤더와 바디를 구분하기 위한 라인
- 바디(Message Body)
- Message Body : 실제 전송받은 데이터
Status Code란??
Status Code란 클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능으로서 3자리 숫자로 구성되어 있으며 100~500번대 숫자로 이루어져 있는 코드를 의미한다.
1. 1xx 번대 코드 : 요청을 받았으며 프로세스를 계속 진행한다는 의미
2. 2xx 번대 코드 : 요청을 성공적으로 받았으며 요청을 인식했고 수용한다는 의미
3. 3xx 번대 코드 : 요청 완료를 위해 추가 작업 조치가 필요하다는 의미
4. 4xx 번대 코드 : 클라이언트 오류로 요청의 문법이 잘못되었거나 요청을 처리할 수 없는 상태를 의미
5. 5xx 번대 코드 : 서버가 명백히 유효한 요청에 대한 충족이 불가능한 상태를 의미
HTTP 메서드
클라이언트와 서버 사이에 이루어지는 요청과 응답 데이터를 전송하는 방식
쉽게 말하면, 서버에 주어진 리소스에 수행하길 원하는 혹은 수행해야 할 동작을 지정하는 요청을 보내는 방법이라고 생각하면 된다.
HTTP 메서드는 총 9가지의 메서드가 있는데...
이는 아래에서 알아보도록 하자!
GET
리소스 조회 메서드 (Read)
GET 메서드는 서버의 상태나 데이터를 변경하지 않고 리소스(데이터)를 가져오는 메서드이다.
응답 결과를 캐싱할 수 있다는 장점이 있고 브라우저 주소창, 링크 클릭, 이미지 로딩 등에 대부분 GET 메서드를 사용한다.
또한, URL에 쿼리 파라미터(/users? id=1)로 데이터를 담아서 사용할 수 있다.
POST
전달한 데이터 처리/생성 요청 메서드 (Create)
POST 메서드는 리소스를 생성하거나 데이터베이스에 변화를 발생시켜 전달한 데이터를 처리하거나 생성하는 것을 요청하는 메서드이다.
요청 Body(Request Body)에 데이터를 포함하여 사용한다.
POST 메서드의 경우, 반복 요청이 발생할 경우 다른 결과를 초래할 수 있기 때문에 멱등성이 없다.
PUT
리소스를 대체(수정)하는 메서드 (Update)
PUT 메서드는 클라이언트가 리소스의 전체 내용을 알고 있을 때, 그 리소스를 덮어씌워 리소스의 정보를 수정하거나 대체하는 메서드이다.
POST와는 다르게 멱등성이 있으며, 반복 요청이 발생하여도 최종적인 결과는 동일하다는 특징이 있다.
대체하려는 리소스가 존재하지 않는 상태라면, 서버 구현에 따라서 새로 생성하는 기능도 수행할 수 있다.
PATCH
리소스 일부 부분을 변경하는 메서드 (Update)
PATCH 메서드는 변경하고자 하는 필드만 요청 Body에 포함하여 전송하면, 서버에서 기존 리소스를 불러와 변경된 필드만 수정하는 방식으로 수행되는 메서드이다.
PUT 보다는 효율적으로 사용할 수 있지만, 적용 방식이 프로그램 구현에 따라 달라지기 때문에 PUT 메서드를 더 대중적으로 사용하고 있다.
DELETE
리소스를 제거하는 메서드 (Delete)
DELETE 메서드는 삭제하고 싶은 정보를 요청 Body에 담아서 서버에 요청하면, 서버에서 해당 정보를 찾아 리소스를 제거하는 메서드이다.
PUT과 동일하게 반복 요청이 발생되어도 최종적인 결과는 동일하기 때문에 멱등성이 있다고 할 수 있는 메서드이다.
HEAD
GET 메서드와 동일한 기능을 하지만 서버에서 Body를 Return 하지 않는 메서드
HEAD 메서드는 GET 메서드와 동일한 요청을 보내되, 응답에서 본문을 제외하고 헤더 정보만 반환받는 메서드이다.
파일의 존재 여부, 마지막 수정 시각, 콘텐츠 타입 등을 확인하는 데 사용하는 메서드이며, 본문이 없기 때문에 대역폭을 절약할 수 있고 리소스 상태 확인이나 캐시 유효성 검사 등에 활용되는 메서드이다.
OPTIONS
서버가 지원하는 메서드 및 옵션을 확인하는 메서드
OPTIONS 메서드는 특정 URL 또는 전체 서버가 어떤 HTTP 메서드를 허용하는지 확인하기 위해 사용되는 메서드이다.
주로 CORS 상황에서 사전 요청으로 주로 사용되고, 브라우저가 실제 요청 전에 서버와 통신 조건을 확인하는 역할을 하고 있다.
응답으로는 Allow라는 헤더가 포함되고, 서버가 허용하는 메서드 목록을 받아온다.
CONNECT
터널을 생성하여 암호화된 통신을 위한 메서드
CONNECT 메서드는 프록시 서버를 통해 터널을 설정할 때 사용되며 주로 HTTPS 요청 시 TLS 터널링을 위해 사용되는 메서드이다.
클라이언트에서 CONNECT 메서드를 보낼 경우, 프록시는 지정된 서버와 TCP 터널을 연결해 준다.
이후 클라이언트는 해당 터널을 통해 암호화된 요청을 직접 전송할 수 있게 된다!
CONNECT 메서드는 주로 보안 통신이나 VPN 연결 등에 활용되고 있다.
여기서...
HTTPS란 HTTP의 보안 버전으로 기본적으로 HTTP와 같지만, 모든 데이터가 암호화되어 전송되는 요청을 의미한다.
여기서 사용되는 암호회는 TLS라는 프로토콜을 사용하여 이루어진다.
그렇다면 TLS 터널링이란 무엇인가...?
우선 TLS 터널은 암호화된 통신 통로를 의미한다.
즉, TLS 터널링은 TLS 터널을 통해 클라이언트와 서버 간의 안전한 통로를 만드는 것을 의미하여, 이때 사용되는 메서드가 바로 CONNECT 메서드인 것이다!
TRACE
요청 경로를 확인하고 디버깅을 위해 사용되는 메서드
TRACE 메서드는 클라이언트가 보낸 요청을 그대로 서버에서 반사해 응답하도록 요청하는 메서드이다.
이를 통해 요청이 중간에 변경되었는지, 프록시나 방화벽이 어떤 영향을 주었는지 확인할 수 있지만...
보안상 민감한 정보가 노출될 가능성이 있기 때문에 대부분의 서버에서는 기본적으로 비활성화되어 있는 메서드이다.
HTTP 메서드의 특징
안전성 (Safe)
메서드가 호출되어도 리소스 변경이 일어나지 않는 속성
여기서 안전의 기준은 오.로.지 리소스 변경 가능성에 의해 결정되며, 이 외의 요소는 포함하지 않는다!
대표적인 메서드로는 GET과 HEAD가 있는데, 이 외의 메서드들은 리소스 변경을 위한 메서드이므로 안전성을 갖진 않는다.
멱등성 (Idempotent)
동일한 요청을 여러 번 보내도 한 번 보내는 것처럼 인식하는 속성
즉 멱등성이란 같은 행위를 여러 번 반복하더라도 같은 효과를 받으며, 서버의 상태로 동일하게 남는 속성을 의미한다.
멱등성은 요청의 결과를 보고 판단하는데, TimeOut 등으로 클라이언트가 서버로부터 정상 응답을 받지 못했을 때 같은 요청을 다시 해도 되는지 판단하는 근거를 얻는다.
GET 메서드의 경우, 몇 번을 조회하더라도 같은 결과가 조회되며 수백 번을 조회한다고 해도 원본 리소스의 정보는 변화하지 않기 때문에 멱등성이 있다고 할 수 있다.
PUT 메서드의 경우, 동일한 PUT 요청이 여러 번 온다고 하더라도 결과를 계속해서 같은 값으로 대체하는 방식으로 결과를 반환하기 때문에 최종 결과는 동일한 결과로 유지된다. 따라서 PUT 메서드 또한 멱등성이 있다고 할 수 있다.
비슷한 원리로 DELETE 메서드 또한 동일한 DELETE 요청이 반복되는 것이라면, 최종 결과는 변함이 없기 때문에 멱등성이 있다고 할 수 있다.
다만, POST 메서드의 경우에는 멱등성이 없다.
POST 메서드를 통해 주문 요청을 한다고 가정했을 때, 동일한 요청이 계속해서 실행된다면 동일한 주문이 계속해서 들어가는 것이기 때문에 에러가 발생할 수 있다.
따라서 POST 메서드에는 멱등성이 없다.
캐시 가능 (Cacheable)
응답 결과를 캐시 하여 사용할 수 있는 속성
음! 여기서 가장 근본적인 의문이 드는데. 캐시란 무엇일까?
캐시란 한 번 받아온 데이터를 임시 저장해 두고, 다음에 같은 데이터를 요청하면 빠르게 가져오는 방식을 의미한다.
간단하게 설명하면, 서버에서 데이터를 계속해서 받는 것이 아니라 브라우저나 중간 서버가 미리 저장해 둔 데이터를 재사용하는 방식을 의미한다.
즉, HTTP 메서드는 응답 결과를 브라우저나 중간 서버에 저장하여 재사용할 수 있는 속성을 지니고 있는 것이다!
마무리...
우선 이번 블로그는 매우 익숙하게 보던 내용들이 많았던 블로그였다.
일단 API를 사용하면서 보았던 각종 메서드들과 HTTP 통신 방식 등은 원래 알던 내용이랑 다른 부분이 없는지 비교하면서 블로그를 쓸 수 있었다. (모르던 내용만 가득했던 블로그 속 한 줄기 빛...)
하지만 HTTP의 특징이나 HTTP 메서드의 특징에 대해서는 알아본 적이 없었기 때문에 추가적으로 알아보며 지식을 쌓을 수 있었다!
특히 이번 블로그의 내용은 프론트엔드 개발을 진행하면서 매일같이 마주하던 내용들이라고 생각해서 더 흥미롭게 작성할 수 있었던 것 같다. (API 연동의 늪)
새로운 내용에 대해서 알아가는 것도 굉장히 좋은 공부라고 생각하지만, 현재 내가 알고 있는 지식이 맞는지 다시 한번 확인하는 것도 굉장히 중요한 공부라는 것을 느낄 수 있었던 이번 블로그...
새로운 내용이든 알고 있던 내용이든 공부를 했다는 점에서 각자 자신에게 칭찬의 박수를 보내며 오늘의 공부를 마무리해 보자👏👏
'CS' 카테고리의 다른 글
| 17. HTTP VS HTTPS (0) | 2025.07.21 |
|---|---|
| 16. 대칭키? 비대칭키? (0) | 2025.07.14 |
| 14. Node.js 환경? 브라우저 환경? (5) | 2025.06.28 |
| 13. 세션, 쿠키, 웹스토리지 (1) | 2025.06.04 |
| 12. React VS Vue.js (0) | 2025.06.03 |
댓글