/*
이 글은 김영한님의 "모든 개발자를 위한 HTTP 웹 기본 지식" 인프런 강좌를 듣고 정리한 글입니다.
강좌 링크> www.inflearn.com/course/http-%EC%9B%B9%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard
*/
1. IP 프로토콜의 한계
A. 비연결성: 패킷을 받을 대상이 없거나 서비스 불능 상태여도 보낸 쪽에서 패킷이 잘 도착했는지 알 수가 없음
B. 비신뢰성: 중간에 패킷이 사라지거나 패킷이 순서대로 안 와도 받는 쪽은 모른다.
C. 한 IP를 여러 프로그램이 사용하면 문제가 생긴다.
2. IP의 한계를 TCP, UDP에서 해결해준다.
A. TCP (Transmission Control Protocol, 전송 제어 프로토콜)
i. 연결지향 (3-way handshake)
1. Client -> Server : SYN
2. Server -> Client : SYN + ACK
3. Client -> Server : ACK
ii. 데이터 전달 보증
iii. 순서 보장
iv. 현재는 대부분 TCP를 사용한다.
B. UDP (User Datagram Protocol)
i. 하얀 도화지에 비유 (기능이 거의 없다)
ii. 연결지향 아님
iii. 데이터 전달 보증 안함
iv. 순서 보장 안함
v. 단순하고 빠르다
vi. IP와 거의 같은데 추가로 PORT, 체크섬 정도만 추가되었다.
vii. 애플리케이션에서 추가적인 작업을 해주어야 한다.
C. 요즘엔 영상 같은 것도 그냥 TCP로 보내서 전체 통신 중 TCP의 비중이 대부분인데, 최근에는 UDP를 다시 쓰는 분야도 나오고 있다.
3. PORT
A. 0 ~ 65535 범위 내에서 할당이 가능하다
B. 0 ~ 1023 은 잘 알려진 포트라 사용하지 않는 게 좋다.
i. FTP : 20 , 21
ii. TELNET: 23
iii. HTTP: 80
iv. HTTPS: 443
4. DNS
A. IP와 도메인 명을 매핑해주는 전화번호부
B. IP를 기억하기 어려웠던 문제와 IP가 변경될 때의 문제를 해결해 줌
5. URI (Uniform Resource Identifier)
A. RFC 3986 표준 스펙에 따르면 URI는 로케이터(locator), 이름(name) 또는 둘 다 추가로 분류될 수 있다.
B. URI가 가장 큰 개념이고, 그 안에 URL과 URN이 있다.
C. URN은 거의 안 쓰고 대부분 URL을 쓴다.
D. 여기선 앞으로 URI를 URL과 같은 의미로 이야기한다.
E. Fragment는 페이지 내에서 이동할 때 URL 뒤에 #을 붙인 후 추가적으로 적은 내용을 가리킨다.
6. HTTP
A. 텍스트, 이미지, 음성, 영상, 파일 등 모든 것이 대부분 HTTP
B. 서버 간에도 대부분 HTTP 사용
C. 바야흐로 HTTP 시대이다. 실무에서 간혹 소켓을 사용하지만 대부분은 HTTP이다.
D. HTTP/1.1
i. 1997년: 가장 많이 사용됨. 우리에게 가장 중요한 버전이다.
ii. 1999, 2014년에 변경이 있었다.
E. HTTP/2
i. 2015년: 성능 개선
F. HTTP/3
i. 현재 진행중: TCP 대신 UDP를 사용하고 성능이 개선되었다.
G. 기반 프로토콜
i. TCP: HTTP/1.1, HTTP/2
ii. UDP: HTTP/3
iii. 현재 HTTP/1.1 주로 사용, 우리도 HTTP/1.1을 기준으로 학습할 예정이다.
iv. 최근 HTTP/2, HTTP/3도 점점 증가하고 있다.
7. 무상태 프로토콜 (Stateless)
A. Stateful (상태 유지): 서버가 클라이언트의 이전 상태를 보존함
B. Stateless (무상태): 서버가 클라이언트의 이전 상태를 보존하지 않음
C. Stateful 모드에서는 서버가 중간에 바뀌면 난리난다.
i. 서버가 중간에 장애가 나면 클라이언트는 작업을 처음부터 다시 해야 한다.
D. Stateless 모드에서는 서버의 확장성이 기하급수적으로 늘어난다.
i. 중간에 어떤 작업을 담당하던 서버가 바뀌어도 된다..!! 다른 서버가 그 다음 작업부터 이어받아서 진행할 수 있기 때문이다.
ii. 갑자기 클라이언트 수가 늘어나면 서버를 늘리면 된다.
E. Stateless 실무 한계
i. 모든 것을 무상태로 설계할 수 있는 경우도 있고 없는 경우도 있다.
ii. 로그인 등은 서버에서 상태를 유지해야 한다.
iii. Stateless 모드는 클라이언트에서 매 요청마다 전달해 주어야 하는 데이터가 Stateful 모드보다 많다는 단점이 있다.
iv. 실무에서는 되도록 Stateless 모드를 가져가려고 하지만 어쩔 수 없이 Stateful 모드를 사용해야 하는 경우도 있다.
8. 비연결성 (Connectionless)
A. TCP/IP는 기본적으로 연결을 유지한다.
i. 클라이언트가 놀아도 서버는 연결을 계속 유지하고 있어야 한다.
B. HTTP는 기본적으로 연결을 유지하지 않는다.
i. 요청이 끝나면 TCP/IP 연결을 끊어버린다.
C. 비연결성
i. HTTP의 기본 컨셉이다.
ii. 일반적으로 초 단위 이하의 빠른 응답 속도를 보여준다.
D. 비연결성 한계와 극복
i. TCP/IP 연결을 매번 새로 맺어야 해서 오버헤드가 꽤나 있다.
ii. 웹 브라우저로 오는 데이터는 HTML 뿐만 아니라 CSS, 이미지 등 많은 자원이 함께 다운로드 되어서 오가는 양도 많다.
iii. 위의 두 문제를 현재는 지속 연결 (Persistent Connections)로 해결하고 있다.
iv. HTTP/2, HTTP/3에서 더 많은 최적화가 되었다.
E. HTTP 지속 연결
i. 요청이 끝나면 바로 연결을 끊지 않고 일정 시간동안 유지한다.
F. 서버 개발자들은 Stateless를 기억하자…!! (서버 개발자들이 어려워하는 업무)
i. 선착순 이벤트, 명절 KTX 예약, 학과 수업 등록 등 정말 같은 시간에 딱 맞추어서 발생하는 대용량 트래픽을 다뤄야 할 상황이 생긴다.
9. HTTP 메시지
A. 요청 헤더에서 주소는 절대 주소이다.
B. HTTP 상태 코드
i. 2XX => 성공
ii. 4XX => 클라이언트 요청 오류
iii. 5XX => 서버 내부 오류
C. HTTP 헤더의 field-name은 대소문자 구분이 없지만, 그에 대응되는 값들은 대소문자 구분이 있다.
D. HTTP 헤더에는 HTTP 전송에 필요한 모든 부가정보가 들어가 있다.
E. HTTP 메시지 바디는 실제 전송할 데이터를 나타낸다.
i. HTML 문서, 이미지, 영상, JSON 등 byte로 표현할 수 있는 모든 데이터가 전송 가능하다.
F. HTTP는 단순하다. 크게 성공하는 표준 기술은 단순하지만 확장 가능한 기술인 듯하다.
10. HTTP API
A. API URI 고민
i. 리소스의 의미는 “회원”이라는 개념 자체이다.
ii. 매핑도 “회원”이라는 리소스에 한다.
B. 주요 메서드
i. GET: 리소스 조회
ii. POST: 요청 데이터 처리, 주로 등록에 사용
iii. PUT: 리소스를 대체, 해당 리소스가 없으면 생성
iv. PATCH: 리소스 부분 변경
v. DELETE: 리소스 삭제
C. 기타 메서드
i. HEAD: GET과 동일하지만 상태줄과 헤더만 반환한다.
ii. OPTIONS: 대상 리소스에 대한 통신 가능 옵션(메서드)을 설명한다. (주로 CORS에서 사용)
iii. CONNECT: 대상 자원으로 식별되는 서버에 대한 터널을 설정한다.
iv. TRACE: 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행한다.
11. POST
A. 201 Created 이면 Location 필드에 신규 생성된 데이터의 위치를 같이 전달해준다.
Ex) /member/{신규 생성된 아이템 ID}
B. POST의 역할
i. 새 리소스를 생성한다.
ii. 요청 데이터를 처리한다.
iii. 다른 메서드로 처리하기 애매한 경우 사용한다.
Ex) JSON으로 조회 데이터를 넘겨야 하는데 GET 메서드를 사용하기 어려운 경우
C. 최대한 리소스로 URI를 설계하되, 리소스만으로는 처리가 안 될 경우에 한해서만 컨트롤 URI를 쓰자.
12. PUT
A. 리소스를 대체한다. (없으면 생성, 있으면 걍 덮어씀)
B. 중요 !!!! 클라이언트가 리소스를 식별한다.
i. 클라이언트가 “리소스의 위치”를 알고 URI를 지정한다. 이것이 POST와의 차이점이다.
13. PATCH
A. 리소스를 부분적으로 변경한다.
B. PATCH가 적용이 안되는 서버도 간혹 있는데, 이 경우엔 POST를 쓰면 된다. POST는 무적이다…
14. DELETE
A. 리소스를 제거한다.
15. HTTP 메서드의 속성
A. 안전 (Safe)
i. 호출해도 리소스를 변경하지 않는다.
B. 멱등 (Idempotent)
i. f(f(x)) = f(x)
ii. 한 번 호출하든 두 번 호출하든 백번 호출하든 결과가 똑같다.
iii. POST!!! 는 멱등이 아니다 !!! 결제를 두 번 하면 결제가 중복된다 !!!!
C. 캐시 가능
i. 응답 결과 리소스를 캐시해서 사용해도 되는가?
ii. GET, HEAD, POST, PATCH 는 캐시 가능하지만 GET, HEAD 정도만 캐시를 사용한다.
iii. POST, PATCH는 본문 내용까지 캐시 키로 고려해야 하는데 구현이 쉽지 않아서 캐시로는 잘 활용하지 않는다.
16. HTTP 메서드의 활용
A. HTML Form 데이터 전송
i. Form 태그에서 Submit하면 POST 메시지의 Content-Type은 application/x-www-form-urlencoded로 전달되고 body 부분에는 GET의 쿼리 파라미터와 유사한 형태로 form 태그의 input 값들이 넘어간다.
Ex) username=kim&age=20
ii. GET으로 Submit하면 POST 할 때의 body 부분을 쿼리 파라미터로 넣어버리기 때문에 제대로 동작하지 않는다. 그러니 Form 태그에서 GET은 데이터를 조회할 때만 쓰자.
iii. Form 태그의 enctype=”multipart/form-data” 는 파일 전송 등 바이너리 데이터를 전송할 때 사용한다. 이 옵션을 사용하면 body 부분이 특정 boundary를 기준으로 여러 파트(multi part)로 나뉘게 된다. Multipart는 GET, POST만 지원한다.
17. HTTP API 데이터 전송
A. 서버와 서버간의 통신, 앱 클라이언트와 서버간의 통신, 웹 클라이언트와 서버간의 통신 등에 사용한다.
B. 사실상 표준인 Content-Type: application/json을 주로 사용한다.
18. HTTP API 설계 예시
A. 컬렉션
i. POST 기반 등록
ii. 클라이언트가 리소스 URI를 모른다.
iii. 서버가 새로 등록된 리소스 URI를 생성해준다.
B. 스토어
i. PUT 기반 등록
ii. 클라이언트가 리소스 URI를 알고 있어야 한다.
iii. 클라이언트가 직접 리소스의 URI를 지정한다.
C. HTML Form 사용
i. GET, POST만 사용한다.
ii. 위 제약으로 인해 실무에서는 /new, /edit, /delete 등의 컨트롤 URI를 사용하는 경우가 많다.
iii. 컨트롤 URI는 생각없이 막 쓰면 안된다.
iv. 컨트롤 URI는 동사를 사용하자.
D. 참고하면 좋은 URI 설계 개념
i. https://restfulapi.net/resource-naming
ii. 절대적인 건 아니지만 좋은 Practice 이다.
19. HTTP 상태 코드 소개
A. 1XX (Informational): 요청이 수신되어 처리중 (거의 사용 안한다.)
B. 2XX (Successful): 요청 정상 처리
C. 3XX (Redirection): 요청을 완료하려면 추가 행동이 필요하다.
D. 4XX (Client Error): 클라이언트 오류, 잘못된 문법 등으로 서버가 요청을 수행할 수 없음
E. 5XX (Server Error): 서버 오류, 서버가 정상 요청을 처리하지 못함
F. 클라이언트가 모르는 상태 코드를 서버가 반환할 경우 클라이언트는 상위 상태코드로 해석한다.
i. 미래에 새로운 상태 코드가 추가되어도 클라이언트를 변경하지 않아도 된다.
ii. 예를 들어 299 코드가 새로 추가되면 2XX로 해석한다.
20. 2XX (성공)
A. 200: OK
B. 201: Created
C. 202: Accepted
i. 배치 처리 등에서 사용한다.
Ex) 일단 큐에 넣고 한 시간 뒤 실행할 때
D. 204: No Content
i. Save하면 결과로 아무 내용이 없어도 된다.
21. 3XX (리다이렉션)
A. 300: Multiple Choices
B. 301: Moved Permanently
C. 302: Found
D. 303: See Other
E. 304: Not Modified
F. 307: Temporary Redirect
G. 308: Permanent Redirect
H. 웹 브라우저는 3XX 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동한다. (리다이렉션)
I. 영구 리다이렉션
i. 특정 리소스의 URI가 영구적으로 이동한다.
ii. 301, 308
iii. 301은 POST로 요청 시 메서드가 GET으로 변하고, 본문이 제거될 수 있다. 사실 대부분 GET으로 변경된다.
iv. 308은 POST로 요청 시 메서드가 POST로 유지되므로 본문이 제거되지 않는다. BUT, 실무에서 이미 새로운 API를 판 거면 데이터 형식도 바뀌어있을 경우가 많아서 주로 308 대신 301을 쓴다.
J. 일시 리다이렉션
i. 일시적인 변경
Ex) 주문 완료 후 주문 내역 화면으로 이동
ii. PRG 패턴: POST / REDIRECT / GET
iii. 302, 307, 303
iv. 302는 리다이렉트 시 301처럼 메서드가 GET으로 변하고, 본문이 제거될 수 있다. 이것도 301처럼 대부분 GET으로 변경된다.
v. 307은 리다이렉트 시 요청 메서드와 본문이 유지된다.
vi. 303은 리다이렉트 시 요청 메서드가 GET으로 변경된다. 302보다 명확하게 메서드를 GET으로 바꾼다.
vii. 일시적인 리다이렉션을 쓰는 경우
1. POST로 주문 후에 웹 브라우저를 새로 고침하면 중복 주문이 될 수 있다. POST로 주문 후에 주문 결과 화면을 GET 메소드로 리다이렉트하면 새로 고침해도 결과 화면을 GET을 조회하기 때문에 중복 주문이 발생하지 않는다.
viii. 307, 303을 권장하지만 현실적으로 302를 이미 많이 사용하고 있다.
K. 특수 리다이렉션
i. 결과 대신 캐시를 사용한다.
ii. 서버 曰: 굳이 나한테서 데이터를 다시 받을 필요 없이 캐시에 있는 거 사용해!!
iii. 300, 304
1. 300은 안쓴다.
2. 304 Not Modified를 많이 쓴다.
A. 캐시 목적으로 사용한다.
B. 클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용한다. (캐시로 리다이렉트한다.)
C. 304 응답은 응답에 메시지 바디를 포함하면 안된다. (로컬 캐시를 사용해야 하므로)
D. 조건부 GET, HEAD 요청 시 사용한다.
22. 4XX
A. 오류의 원인이 클라이언트에 있다.
i. 중요!! 클라이언트의 똑같은 재시도가 똑같이 실패한다.
ii. 서버 개발자는 4XX 오류를 철저하게 튕겨내주어야 한다. 안 그러면 클라이언트 개발자는 오류 발생 시 서버 문제로 생각하기 쉽다.
iii. 400 Bad Request: 문법 오류
iv. 401 Unauthorized: 인증이나 인가 발생 시 발생
1. 응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명한다.
2. 인증(Authentication): 본인이 누구인지 확인 (로그인)
3. 인가(Authorization): 권한 부여 (ADMIN 권한처럼 특정 리소스에 접근할 수 있는 권한, 인증이 있어야 인가가 있음)
v. 403 Forbidden
1. 서버가 요청을 이해했지만 승인을 거부
2. 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우
vi. 404 Not Found: 요청 리소스가 서버에 없음
23. 5XX
A. 오류의 원인이 서버에 있다.
B. 웬만해서는 서버에서 5XX 에러를 만들면 안된다.
C. 503 Service Unavailable
i. 서비스 이용 불가
ii. 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
iii. Retry-After 헤더 필드로 얼마 뒤에 복구되는지 보낼 수도 있음
24. HTTP 헤더 개요
A. 용도: HTTP 전송에 필요한 모든 부가정보
B. 메시지 바디 내용, 바디 크기, 압축 정보 등..
C. 헤더 분류
i. General 헤더: 메시지 전체에 적용되는 정보( Connection 등)
ii. Request 헤더: 요청 정보 (User-Agent 등)
iii. Response 헤더: 응답 정보 (Server 등)
iv. Entity 헤더: 엔티티 바디 정보 등 (Content-Type 등)
D. RFC723x 변화
i. 용어가 엔티티(Entity)에서 표현(Presenstation)으로 바뀜
E. HTTP Body
i. 메시지 본문(Message Body)을 통해 표현(Representation) 데이터 전달
ii. 메시지 본문을 페이로드(payload)라 읽음
iii. 표현은 요청이나 응답에서 전달할 실제 데이터
iv. 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공
1. 데이터 유형(HTML, JSON), 데이터 길이, 압축 정보 등..
25. 표현 (Representation)
A. Content-Type: 표현 데이터의 형식
Ex) text/html; Charset=utf-8
Ex) application/json
Ex) image/png
B. Content-Encoding: 표현 데이터의 압축 방식
Ex) gzip, deflate, identity(압축 안함)
C. Content-Language: 표현 데이터의 자연 언어 (한국어, 영어 등)
Ex) ko, en, en-US
D. Content-Length: 표현 데이터의 길이
i. 바이트 단위
ii. Transfer-Encoding을 사용하면 Content-Length를 사용하면 안된다
26. 협상 (Content Negotiation)
A. 클라이언트가 선호하는 표현 요청을 알려줌
B. Accept: 클라이언트가 선호하는 미디어 타입 전달
C. Accept-Charset: 클라이언트가 선호하는 문자 인코딩
D. Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
E. Accept-Language: 클라이언트가 선호하는 자연 언어
F. 협상 헤더는 요청시에만 사용
G. Quality Values(q) 값으로 우선 순위를 매길 수 있음
Ex) Accept-Language: ko-KR, ko;q=0.9,en-US;q=0.8,en;q=0.7
H. 우선순위는 구체적인 것이 우선한다.
Ex) Accept: text/*, text/plain, text/plain;format=flowed, */*
1) text/plain;format=flowed
2) text/plain
3) text/*
4) */*
27. HTTP 전송 방식
A. 단순 전송 (Content-Length): Content-Length를 딱 지정할 수 있다.
B. 압축 전송 (Content-Encoding)
C. 분할 전송 (Transfer-Encoding)
i. Transfer-Encoding: chuncked
ii. “데이터 전송 길이 + 데이터” 를 연달아 보내주고 마지막에 “\r\n”을 붙여서 끝을 알림
iii. Content-Length는 고정되어 있지 않기 때문에 넣으면 안됨
D. 범위 전송 (Range, Content-Range): Content-Range 필드에 내가 원하는 데이터 범위를 알려줌
28. 일반 정보
A. From: 유저 에이전트의 이메일 정보: 보통 사용되지 않음
B. Referer: 이전 웹 페이지 주소
i. Referer를 사용해서 유입 경로 분석 가능
ii. 요청에서 사용
iii. Referer는 단어 referrer의 오타
C. User-Agent: 유저 에이전트 어플리케이션 정보
i. 통계 정보에 도움이 됨
ii. 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
iii. 요청에서 사용
D. Server: 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
i. 중간에 거쳐가는 장비들 말고 최종적으로 end단에 있는 서버의 정보
ii. 응답에서 사용
E. Date: 메시지가 발생한 날짜와 시간
i. 응답에서 사용 (과거에는 요청에서도 사용했었음)
29. 특별한 정보
A. Host: 요청한 호스트 정보(도메인) !!!!!!
i. 필수다!!!!!!!!!!
ii. 요청에서 사용
iii. 서버에서 가상 호스팅을 할 경우 클라이언트의 요청을 제대로 매핑하기 위해 호스트 정보가 필수이다.
B. Location: 페이지 리다이렉션
C. Allow: 허용 가능한 HTTP 메서드
i. 405(Method Not Allowed)에서 응답에 포함해야 함
ii. 많이 쓰이진 않는다.
D. Retry-After: 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
30. 인증
A. Authorization: 클라이언트 인증 정보를 서버에 전달
B. WWW-Authenticate: 리소스 접근 시 필요한 인증 방법을 정의
31. 쿠키
A. Set-Cookie: 서버에서 클라이언트로 쿠키 전달 (응답)
B. Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청 시 서버로 전달
C. HTTP는 무상태(Stateless) 프로토콜이라 기본적으로 로그인 정보를 유지하지 않음
D. 주 사용처
i. 사용자 로그인 세션 관리
ii. 광고 정보 트래킹
E. 쿠키 정보는 항상 서버에 전송됨
i. 네트워크 트래픽 추가 유발
ii. 최소한의 정보만 사용 (세션 id, 인증 토큰)
iii. 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지(localStorage, sessionStorage) 참고
iv. 주의!! 보안에 민감한 데이터는 절대 저장하면 안됨 !!! (주민번호, 신용카드 정보드 등)
F. 생명 주기
i. Expires, max-age 로 설정 가능
ii. 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시까지만 유지
iii. 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지
G. 도메인(Domain)
i. 아무 사이트에 들어갈 때마다 쿠키가 막 생기면 좀 곤란함..
ii. 하나의 쿠키를 하위 도메인에서도 사용할 수 있게 해줌
H. 경로(Path)
i. 이 경로를 포함한 하위 경로 페이지만 쿠키 접근
ii. 일반적으로 path=/루트로 지정
I. 보안(Secure, HttpOnly, SameSite)
i. Secure
1. 쿠키는 http, https를 구분하지 않고 전송
2. Secure를 적용하면 https인 경우에만 전송
ii. HttpOnly
1. XSS 공격 방지
2. 자바스크립트에서 접근 불가 (document.cookie)
3. HTTP 전송에만 사용
iii. SameSite
1. XSRF 공격 방지
2. 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송
3. 이건 최근에 추가된거라 브라우저에서 얼마나 지원해주는지 확인해 봐야 함
32. 캐시 기본 동작
A. 캐시가 없을 때 매번 인터넷 네트워크를 타야 하는데, 컴퓨터에서 이 cost는 꽤나 비싸고 느리다.
B. 캐시 적용 시간을 지정해줄 수 있음
i. 캐시 가능 시간동안 네트워크를 사용하지 않아도 됨
Ex) cache-control: max-age=60
33. 검증 헤더와 조건부 요청
A. if-modified-since: 캐시가 가지고 있는 데이터 최종 수정일
1) 클라이언트가 서버에게 데이터를 요청
2) 서버가 클라이언트에게 데이터를 보낼 때 Last-Modified를 알려줌
3) 클라이언트가 서버에게 데이터를 다시 요청
4) 서버에서 자신이 가지고 있는 데이터가 클라이언트의 데이터보다 예전꺼거나 동일하면 HTTP응답에 304 Not Modified로 보내주고 HTTP Body를 아무것도 없이 보냄
B. 캐시 유효 시간이 초과해도, 서버의 데이터가 갱신되지 않으면 304 Not Modified + 헤더 메타 정보만 응답으로 보냄 (Body X). 매우 실용적이어서 대부분 이 검증을 사용한다.
C. Last-Modified, if-Modified-Since의 단점
i. 1초 미만 캐시 조정이 불가능하다.(굳이?)
ii. 날짜 기반의 로직 사용
iii. 데이터를 사정해서 날짜가 다르지만, 같은 데이터를 수정해서 데이터 결과가 똑같은 경우 다시 다 다운로드함
iv. 스페이스나 주석을 무시하는 등 서버에서 별도의 캐시 로직을 관리하지 못함 (ETag의 출현)
D. ETag (Entity Tag)
i. 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠
ii. 데이터가 변경되면 이 이름을 바꾸어서 변경함 (Hash를 다시 생성)
iii. 진짜 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받기
iv. 클라이언트가 요청할 때 If-None-Math 로 캐시된 ETag를 보냄
v. 캐시 제어 로직을 서버에서 완전히 관리!!!(클라이언트에게는 캐시 제어 로직이 블랙박스)
34. 캐시와 조건부 요청 헤더
A. Cache-Control: 캐시 지시어 (directives)
i. Max-age: 캐시 유효 시간 초 단위
ii. No-cache: 데이터는 캐시해도 되지만, 항상 원(origin) 서버에 검증하고 사용
iii. No-store: 데이터에 민감한 정보가 있으므로 저장하면 안됨 (메모리에서 사용하고 최대한 빨리 삭제)
B. Pragma: 캐시 제어
i. 하위 호환을 위해 남겨두었지만 Cache-Control로 대체 가능
C. Expires: 캐시 만료일 지정
i. 하위 호환을 위해 남겨두었지만 Cache-Control로 대체 가능
35. 프록시 캐시
A. 프록시 캐시 서버: CDN 서비스 등에서 많이 쓰이는 개념
B. 프록시 캐시 서버에 저장되는 캐시를 public 캐시, 사용자 PC에 저장되는 캐시를 private 캐시라 부름
C. Cache-Control: public
i. 응답이 public 캐시에 저장됨
D. Cache-Control: private
i. 응답이 해당 사용자만을 위한 것임, private 캐시에 저장해야 함 (기본값)
E. Cache-Control: s-maxage
i. 프록시 캐시에만 적용되는 max-age
F. Age: 60 (HTTP 헤더)
i. 오리진 서버에서 응답 후 프록시 캐시 내에 머무는 시간 (초)
36. 캐시 무효화
A. 사용자가 캐시를 사용하지 않아도 브라우저가 휴리스틱하게 캐시를 하기도 함
i. 이럴 경우 명시적으로 캐시 무효화를 해주어야 함
B. 확실한 무효화를 하려면 Cache-Control과 Pragma를 지정해주어야 함
i. Cache-Control: no-cache, no-store, must-revalidate
1. must-revalidate: 원 서버에서 꼭 유효성 검사를 해야한다는 의미로 네트워크 등의 문제로 유효성 검사가 안 될 경우 절대로 캐시 데이터를 사용하면 안됨을 명시
ii. Pragma: no-cache (HTTP 1.0 하위 호환)