일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 객체지향
- 깃허브 저장소 합치기
- 스프링
- REST #REST API #HTTP 메서드
- ExceptionResolver
- 스프링 컨테이너
- HTTP메시지
- 스프링 파일 업로드
- http
- HTTP 요청 메시지
- 백준4256
- HTTP 응답 메시지
- BeanDefnition
- 서블릿
- BasicErrorController
- 프로토콜 스택 4계층
- 김영한
- 스프링 빈
- 스프링 타입컨버터
- 프로토타입 스코프
- DI
- 체크에러
- BeanValidation
- 커밋로그
- 예외추상화
- 의존관계
- 언체크에러
- 스프링 예외변환기
- 웹 스코프
- 백준 2263
- Today
- Total
Enthusiasm! Enthusiasm!
HTTP 헤더 본문
HTTP 개요
1999년에 나온 HTTP표준인 RFC2616이 폐기되고 2014년에 RFC7230~7235가 등장하였다. 그에 따라 이전에 엔티티(Entity)라 칭했던 내용들이 표현(Representation)으로 변경되었다. 표현은 표현 메타데이터와 표현 데이터를 합친 것이다.
표현 데이터는 메시지 본문(message body)를 통해 표현 데이터를 전달한다. 표현 헤더는 표현 데이터를 해석할 수 있는 정보를 제공한다.
표현 헤더
표현데이터를 해석할 수 있는 정보를 제공하는 표현 헤더는 여러 종류의 정보를 담을 수 있다.
- Content-Type: 미디어 타입, 문자 인코딩 등 표현 데이터의 형식을 설명한다.
- ex) text/html;charset=UTF-8, application/json, image/png
- Content-Encoding: 표현 데이터를 압축하기 위해 사용된다. 데이터를 전달하는 곳에서 압축 후 인코딩 헤더를 추가하면, 읽는 쪽에서 인코딩 헤더의 정보로 압축을 해제한다.
- ex) gzip, deflate, identity
- Content-Language: 표현 데이터의 자연 언어 정보이다.
- ex) ko, en, en-US
- Content-Length: 표현 데이터의 길이 정보이며 바이트 단위이다.
- ex) Content-length:5
협상 헤더
요청시에만 사용되는 헤더로 클라이언트가 선호하는 표현 요청 정보이다. 대표적으로 Accept-Language가 있다.
Accept-Language:ko 헤더를 통해 한국어를 선택할 수 있게 되었다. 또한 협상에는 우선순위를 부여할 수 있다.
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7 과 같이 우선순위를 부여하여 전송하면 된다. 값이 클 수록 우선순위가 높으며, 서버가 우선순위에 따라 언어를 지정한다.
Accept: text/*, text/plain, text/plain;format=flowed, */* 과 같이 전송해도 우선순위가 있는데, 이때는 구체적인 것이 높은 우선순위를 갖는다.
기타 헤더들
이 외에도 전송방식을 설명하는 Transfer-Encoding 헤더, 일반 정보(From, Refeter, User-Agent, Server, Date ...등)를 담은 헤더, 특별한 정보(Host, Location, Allow, Retry-After)를 담은 헤더등이 있다.
쿠키
HTTP는 무상태 프로토콜이기 때문에 클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다. 즉 클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다. 하지만 로그인과 같이 상태를 유지해야 하는 상황이 있다. 이때는 쿠키를 사용하면 된다.
쿠키를 사용하면 모든 요청에 쿠키 정보가 자동으로 포함된다. 모든 요청에 전송되기 때문에, 최소한의 정보(세션 id, 인증 토큰)만 전송해야한다. 또한 보안에 민감한 데이터를 저장해서는 안된다.
쿠키의 생명주기
-만료일 지정: Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT -> 만료일을 지정해주고 만료일이 되면 쿠키를 삭제한다.
-일정 시간 지속: Set-Cookie: max-age=3600 (3600초) -> 일정 시간동안만 쿠키가 지속되도록 설정한다.
-세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시까지만 유지한다.
※쿠키의 경로를 설정해줄 때는 일반적으로 path=/루트로 지정해준다.
캐시
어떤 이미지 파일을 조회한다 가정해보자, 첫번째 조회에서는 아래 그림과 같이 파일의 모든 데이터를 다운받아야 한다.
곧바로 두번째 요청을 한다 가정해보자, 이미지 파일의 데이터 변경이 없음에도 모든 데이터를 다운받는다면, 많은 자원의 낭비가 발생하고 로딩이 지연될 것이다. 이는 캐시를 사용하여 해결하면 된다.
서버가 첫번째 응답을 할 때 cache-control: max-age=60과 같이 응답헤더에 캐시에 대한 정보를 넣어주면, 캐시가 유효한 시간동안 직접 데이터를 받지않고 브라우저 캐시에서 데이터를 조회할 수 있게 되고 비효율성을 어느정도 해결할 수 이다.
하지만 위 방법도 완전한 해결방법은 될 수 없다. 캐시 유효시간이 지난 이후에 데이터가 바뀌지 않았는데 다시 다운로드 받는것 또한 비효율적이기 때문에 이 문제점도 해결해보자.
검증 헤더와 조건부 요청
캐시 유효 시간이 초과해서 서버에 다시 요청하면 다음 두 가지 상황이 나타난다.
- 서버에서 기존 데이터를 변경함
- 서버에서 기존 데이터를 변경하지 않음
1번 상황에서는 데이터를 다시 다운로드 받아야 하지만, 2번 상황에서는 데이터를 다운받는 것 보다 저장해두었던 캐시를 재사용하는게 더 효율적일 것이다. 단 클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법이 필요하다. 이를 위해 검증헤더와 조건부 요청이 사용된다.
- 첫번째 방법

위 그림과 같이 데이터가 마지막에 수정된 시간에 대한 정보인 Last-Modified 정보를 함께 넣어 클라이언트에 보낸다. 클라이언트에서 캐시가 만료되고 서버에 다시 요청을 보낼 때 if-modified-since: 2020년 11월 10일 10:00:00 과 같이 헤더에 조건부 요청을 보내, 데이터를 수정하지 않았다면 아래 그림과 같이 304 Not Modified + 헤더 메타 정보만 응답(바디X) 정보만 보내면 된다. 클라이언트는 이 응답 헤더 정보로 캐시의 메타정보를 갱신하여 캐시 데이터를 재활용 할 수 있다.

하지만 이 방법에는 몇 가지 단점이 존재한다.
- 날짜 기반의 로직을 사용하기 때문에 1초 미만 단위로 캐시 조정이 불가능하다.
- 데이터를 수정해서 날짜가 다르지만, 데이터를 수정한 결과가 같을 때 이를 구분할 수 없다. (a-b 수정 후 b-a 수정)
- 서버에서 별도의 캐시 로직을 관리하고 싶은 경우 처리할 수 없다. (스페이스나 주석처럼 데이터가 변해도 영향이 없는 변경일 때는 캐시를 유지하고 싶을 때)
이러한 문제점을 보완하기 위해 ETag와 If-None-Match가 등장했다.
- 두번째 방법
-ETag(Entitiy Tag): 캐시용 데이터에 임의의 고유한 버전 이름(Hash값으로 설정)을 달아둠, 데이터가 변경되면 이 이름을 바꾸어서 해시값을 재설정 한다. 단순히 ETag만 보내서 같으면 캐시를 유지하고 다르면 다시 받는다!

이 방법을 사용하면, 캐시 제어로직을 서버에서 완전히 관리할 수 있다. 클라이언트는 단순히 이 값을 서버에 제공하기만 하면 된다!
일정 기간동안 파일이 변경되어도 ETag를 그대로 유지하고, 배포 주기에 맞춰 바뀐 파일에 대한 ETag를 모두 갱신하여 배포하는 방식으로 활용도 가능하다.
캐시 지시어
캐시 제어 헤더에는 Cache-Control, Pragma, Expires과 같이 3가지 종류가 있다.
- Cache-Control: 캐시 제어
- Cache-Control: max-age: 캐시 유효시간, 초단위
- Cache-Control: no-cache: 데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용(최종 서버에 데이터가 바뀌었는지 검증해서 사용)
- Cache-Control: no-store: 데이터에 민감한 정보가 있으므로 저장하면 안된다.
- Pragma: 캐시 제어(하위 호환): 지금은 거의 사용하지 않지만, 이전 버전 호환을 위해 사용된다.
- Pragma: no-cache
- Expires: 캐시 만료일 지정(하위 호환)
- 캐시 만료일을 정확한 날짜로 지정
- 지금은 더 유연한 Cache-Control: max-age 사용이 권장된다.
캐시 무효화
캐시 지시어를 통해 확실한 캐시 무효화를 할 수 있다. 절대 캐시되면 안되는 데이터를 처리할 때 다음 명령어를 전부 넣어줘야 한다.
- -Cache-Control: no-cache, no-store, must-revalidate
- -Pragma: no-cache : 예전 페이지와의 호환을 위해 넣어줘야한다.
※must-revalidate: 원서버 조회시 문제가 발생하면 반드시 오류가 발생해야한다.
위 3개를 조합하면 캐시를 저장하지 못하고, 만약 캐시가 있으면 반드시 서버에 검증해야하고, 문제가 발생하면 반드시 오류가 발생한다.
이전 포스팅-https://yulddong.tistory.com/22
HTTP 상태코드
HTTP 상태코드 이전 포스팅에서는 클라이언트에서 서버로 데이터를 요청하는 과정을 알아보았다. 클라이언트가 요청 시 서버는 응답 메시지를 생성하는데HTTP 상태코드란 클라이언트가 보낸 요
yulddong.tistory.com
이 포스팅은 모든 개발자를 위한 HTTP 웹 기본지식 (By Inflearn 김영한님) 강의 및 강의자료를 참고하여 작성하였습니다.
'자바 스프링 > HTTP웹 기본지식' 카테고리의 다른 글
HTTP 상태코드 (1) | 2023.02.02 |
---|---|
HTTP 메서드 (0) | 2023.01.29 |
HTTP 기본 (0) | 2023.01.27 |
인터넷 네트워크와 웹 브라우저 요청 흐름 (0) | 2023.01.16 |