티스토리 뷰

Hyper Text Transfer Protocol 의 약자로, 인터넷에서 데이터를 주고받는 통신규약(프로토콜)이다.

이렇게 규칙을 정해두었기 때문에, 모든 프로그램이 서로 정보를 교환할 수 있게 된 것이다. 

 

웹 개발자라면 HTTP 지식이 필수조건이다. FE개발자의 역할 중 하나가 서버로 데이터를 전송하는 것이기 때문에 HTTP를 모른다면 역할을 다하고 있다고 말할 수 없다.

 

데이터를 주고 받을 때 흔히 발생하는 CORS, CORB(?) 같은 에러들은 HTTP만 잘 알아도 쉽게 해결이 가능하다. 

(실제로 http 지식이 전무할 때, api호출을 하면서 엄청난 오류를 겪었고 해결하는데도 시간이 걸렸다.)

 

서버의 역할이 요청에 대한 응답을 보내준다는 것을 기억하자.

HTTP/1.1을 기준으로 설명

 

요청과 응답은 메세지 형식으로 오고, 메세지는 시작줄, 헤더, 본문으로 구성되어 있다.

HTTP 메서드

요청을 할 때, 주소와 함께 HTTP 메서드를 같이 보낼 수 있다. 자주 쓰는 HTTP 메서드는 GET, POST, PUT, PATCH, DELETE 정도가 있다. 

  • GET: 가져오다
  • POST: 게시하다
  • PUT: 집어넣다
  • PATCH: 고치다
    • 보통 PUT은 전체 수정(대체), PATCH는 부분 수정
  • DELETE: 지우다 
GET과 DELETE를 제외한 POST, PUT, PATCH는 요청을 보낼 때 본문을 같이 보낼 수 있다. GET, DELETE에도 본문을 보내도 되지만 본문을 어떻게 처리해야한다는 정의가 없기 때문에 본문을 같이 보내지 않음

잘 사용하던 예시로는 HTML 폼에서 method 속성으로 Get과 Post를 사용할 수 있다. action에는 주소가 들어가고 보통 새로운 글을 등록할 때 POST로 설정하고 폼을 사용한다. 즉, 지금까지 POST action주소 HTTP/1.1(버전)로 요청을 보내온 것이다. 인풋 태그 데이터들은 요청의 본문으로 들어간다.

(BE개발자님이 폼데이터로 보내주시나요? 라고 했던 게 처음에는 이해하지 못해서 당황했었는데 .. 이제는 무슨 소리인지 확실히 알 수 있다.)

 

클라이언트에서 POST요청을 보낼 때, Request Payload 부분이 본문 부분이다.  

헤더 다음에 본문이 들어가는 형태인데 서버가 저 본문을 받아 파싱(해석)한 후 사용하게 된다.

 

GET에 데이터를 담아서 보내고 싶다면 보통 Query String Parameters를 같이 보낸다. 

주소 뒤에 ?를 붙인 후 키=값&키=값 식으로 표현된게 query string이며 GET요청은 본문 대신 주소에 쿼리스트링을 통해 데이터를 동봉한다.

 

외에도 OPTIONS 메서드가 있는데 이 옵션은 서버가 어떤 메서드를 지원하는 지 알아볼 때 사용된다.

CORS 상황에서는 다른 도메인 서버에 먼저 OPTIONS 요청을 날린 뒤, 그 서버가 요청을 허용하면 실제 요청을 날린다. 

간단하게 서버에 실제 요청을 보내기 전에 서버를 테스트해보는 용도라고 생각하면 된다.

+ CONNECT는 양방향 통신을 할 때 쓰인다. 

 

1. 공통 헤더

요청과 응답에 모두 사용되는 헤더이다. 이 중에서 Content 시리즈는 엔티티 헤더라고 불린다.

 

1-1. Date 

HTTP 메세지가 만들어진 시각 (자동으로 생성)

1-2. Connection

기본적으로 keep-alive로 되어있는데 사실상 의미가 없다. HTTP/2에서는 아예 사라짐

1-3. Cache- Control 

매우 중요하고 알아두어야 하는 헤더

1-4. Content-Type

컨텐츠의 타입(MIME)과 문자열 인코딩(utf-8 등등)을 명시할 수 있다. 조금 뒤에 오는 Accept 헤더, Accept-Charset 헤더와 대응된다. 

> 프론트에서 서버로 데이터를 보낼 때는 text/html 이런 것 대신 www-url-form-encoded 나 multipart/form-data 같은 게 Content-Type이된다. 

1-5. Content-Language

사용자의 언어를 뜻하며 요청이나 응답이 무슨 언어인지와는 관계 없음

예를 들어 한국 사람한테 일본어를 가르치는 사이트일 경우, 페이지 언어는 일본어이더라도 Content-Language는 ko-KR일 수 있다. 

1-6. Contetn-Encoding

컨텐츠가 압축된 방식을 말한다. 응답 컨텐츠를 br, gzip, deflate 등의 알고리즘으로 압축해서 보내면, 브라우저가 알아서 해제해서 사용한다. 이 외에도 다양한 압축 알고리즘이 존재하며 컨텐츠 용량이 줄어들기 때문에 압축을 권장한다. 

> 요청이나 응답 전송 속도도 빨라지고, 데이터 소모량도 줄어들기 때문에 가능하면 압축!


2. 요청(Request) 헤더

2-1. Host

서버의 도메인 네임이 나타나는 부분(포트 포함)

> Host 헤더는 반드시 하나가 존재해야 한다.

2-2. User-Agent

Host 보다 더 유명한 헤더이다. 현재 사용자가 어떤 클라이언트(운영체제와 브라우저 같은 것)을 이용해 요청을 보냈는 지 나온다.

> 물론 유저 에이전트를 믿어서는 안된다. 헤더를 조작했을 수도 있음 하지만 대부분의 사람이 유저 에이전트를 조작하지 않고 그대로 보내기 때문에, 유저 에이전트 헤더를 활용해서 접속자 통계를 내곤 한다.

2-3. Accept

Accept 헤더는 요청을 보낼 때 서버에 이런 타입(MIME)의 데이터를 보내줬으면 좋겠다고 명시할 때 사용한다.

e.g.) Accept: text/html  -> HTML 형식인 응답을 처리하겠다는 뜻

Accept: image/png, image/gif

Accept: text/* 

콤마로 여러 타입을 동시에 적어줄 수도 있고, *(와일드 카드)로 텍스트이기만 하면된다고 적어줄 수 있다.

 

Accept 시리즈라 한 이유는, Accept-Encoding, Accept-Charset, Accept-Language 등도 있기 때문이다. 

공통 헤더의 Content 시리즈와 대응된다. Accept로 원하는 형식을 보내면, 서버가 그에 맞춰 보내주면서 응답 헤더의 Content를 알맞게 설정한다. 

> 뭘 적어야할 지 모르겠다면 *(와일드카드)를 적거나, 그냥 브라우저가 알아서 설정해서 보내는 Accept 를 사용하면 된다.

 

2-4. Authorization 

인증 토큰(JWT, Bearer 토큰이든)을 서버로 보낼 때 사용하는 헤더

2-5. Origin

Post같은 요청을 보낼 때, 요청이 어느 주소에서 시작되었는지를 나타낸다.

> 여기서 요청을 보낸 주소와 받는 주소가 다르면 CORS 문제가 발생하기도 한다.

2-6. Referer

이 페이지 이전의 페이지 주소가 담겨있다. 이 헤더를 사용하면 어떤 페이지에서 지금 페이지로 들어왔는지 알 수 있기 때문에 애널리틱스같은 데 많이 사용된다. 


3. 응답(Response) 헤더

3-1. Access-Control-Allow-Origin

프론트에서 악명 높은 헤더이다. 요청을 보내는 프론트 주소와 받는 백엔드 주소가 다르면 CORS 에러가 발생한다.

> 이 때 서버에서 응답 메세지의 Access-Control-Allow-Origin 헤더에 프론트 주소를 적어주어야 에러가 나지 않는다.

프로토콜, 서브 도메인, 도메인, 포트 중 하나만 달라도 CORS 에러

유사한 헤더로  Access-Control-Request-Method, Access-Control-Request-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Headers 등이 있다.

 

CORS 요청 시에는 미리 OPTIONS 주소로 서버가 CORS를 허용하는 지 물어보고 이 때, Access-Control-Request-Method로 실제로 보내고자 하는 메서드를 알리고, Access-Control-Request-Headers로 실제로 보내고자 하는 헤더들을 알려준다. Allow 는 Request에 대응되는 친구들로, 서버가 허용하는 메서드와 헤더를 응답하는 데 사용된다.

> Request 와 Allow가 일치하면 CORS 요청이 이루어진다. 

 

3-2. Allow

Allow 헤더는 Access-Control-Allow-Methods 와 비슷하지만, CORS 요청 외에도 적용된다는 차이가 있다.

> GET www.도메인예시.com  은 되고 POST www.도메인예시.com  은 허용하지 않는 경우, 405 Method Not Allowed 에러를 응답하면서 헤더로 Allow: GET 을 같이 보내면 된다. (GET 요청만 받겠다는 뜻)

 

3-3. Content-Disposition 

응답 본문을 브라우저가 어떻게 표시해야 할 지 알려주는 헤더이다.

inline인 경우 웹페이지 화면에 표시되고, attachment 인 경우 다운로드 된다. 

e.g.) Content-Disposition: attachment; filename="filename.csv'

> 다운로드되길 원하는 파일은 attachment로 값을 설정하고, filename 옵션으로 파일명까지 지정해줄 수 있다. 

파일용 서버인 경우 이 태그를 자주 사용하게 될 것이다.

3-4. Location

300번대 응답이나 201 Created 응답일 때 어느 페이지로 이동할지를 알려주는 헤더이다.

e.g.)

HTTP/1.1 302 Found

Location: /

이런 응답이 왔다면 브라우저는 / 주소로 리다이렉트한다.

3-5. Content-Security-Policy

다른 외부 파일들을 불러오는 경우, 차단할 소스와 불러올 소스를 여기에 명시할 수 있다. 

하나의 웹 페이지는 다양한 외부 소스를 불러오는데 이미지, 폰트, 스타일, 아이프레임, script 태그로 자바스크립트 파일들도 불러온다.

> XSS 공격같은 악성 코드가 남긴 파일을 불러오면 안되기 때문에 Content-Security-Policy로 허용할 외부 소스만 지정해줄 수 있다.

*옵션이 매우 많기 때문에 공식 문서를 참고하는 것이 좋다.


4. 캐시 헤더

웹 자원을 효율적으로 사용하기 위해서는 캐싱이 중요하다. 똑같은 데이터를 계속해서 내려 받을 필요 x 

쿠키는 클라이언트와 서버 간에 데이터를 주고받는 가장 간단한 방법 중 하나이다. 

 

캐시

여기서 말하는 캐시는 CDN같은 공유 캐시가 아니라 개인 캐시를 뜻한다. 브라우저에 응답으로온 HTML이나 JSON같은 데이터가 저장되어 나중에 서버에 요청을 보내지 않고도 브라우저에 저장된 응답을 사용할 수 있다. 

> 보통 캐싱은 GET 요청에만 한다. 다른 요청 메서드를 캐싱하는 것은 잘 보지 못했다. 일반적으로 200(가져오기 성공), 301(다른 주소로 이동 후 가져옴), 404(가져올 게 없음) 상태 코드로 온 응답을 캐싱할 수 있다. 

 

4-1.Cache-Control

많은 옵션이 있지만 자주 쓰이는 옵션만 보자

e.g.) Cache-Control: no-store -> 아무 것도 캐싱하지 않으려면 

Cache-Control: public 또는 private ->public이면 공유 캐시(또는 중개 서버)에 저장해도 된다는 뜻이고 private이면 브라우저같은 특정 사용자 환경에만 저장하라는 뜻

max-age로 캐시 유효기간을 줄 수 있다. 초 단위(max-age=3600 //1시간)

> Cache-Control을 응답 헤더라고 생각할 수 있지만 요청 헤더로도 사용할 수 있다.(프론트에서 조작가능)

프론트 - 중개 서버 - 진짜 서버와 같은 구조인 경우에 중개 서버에 있는 캐시를 가져오지않도록 하려면 요청 시부터 Cache-Control을 헤더로 넣어주곤 한다.

 

4-2. ETag

HTTP 컨텐츠가 바뀌었는지를 검사할 수 있는 태그이다. 같은 주소의 자원이더라도 컨텐츠가 달라졌다면 ETag가 다르다.

e.g) 응답 본문이 "동글동글"이고 ETag 헤더 값이 12345라고 치자. 만약 서버 컨텐츠(응답 본문)이 동일하다면 매번 GET을 할 때마다 ETag는 12345이다. 하지만 "동글동글"에서 "네모네모"로 컨텐츠가 변경되었다면 ETag 헤더 값도 23435로 바뀐다. 그러면 서버가 클라이언트 응답 내용이 달라졌음을 깨닫게 되어 캐시를 지우고 새로 컨텐츠를 내려받을 수 있게 된다. 

 

4-3. If-None-Match

서버보고 Etag가 달라졌는 지 검사해서 Etag가 다를 경우에만 컨텐츠를 새로 내려주라는 뜻이다.

e.g) If-None-Match: W/"3bf2-wdj3VvN8/CvXVgafkI30/TyczHk"

> 만약 ETag가 같다면 서버는 304 Not Modified를 응답해서 캐시를 그대로 사용하게 된다.

 

+a:  HTTP X 헤더

이 내용은 zero cho 님의 사이트를 참고하면 된다.

 

all ref: https://www.zerocho.com/category/HTTP

 

HTTP

HTTP 관련 글 리스트입니다

www.zerocho.com

https://developer.mozilla.org/ko/docs/Web/HTTP

 

HTTP | MDN

하이퍼텍스트 전송 프로토콜(HTTP)은 HTML과 같은 하이퍼미디어 문서를 전송하기 위한 애플리케이션 레이어 프로토콜입니다. 웹 브라우저와 웹 서버간의 통신을 위해 설계되었지만 다른 목적으로

developer.mozilla.org

 

댓글