CORS는 이번에 처음 접해본 개념이라 아직 완전하게 숙지하지 못했다. 주말에 찬찬히 MDN문서를 읽으며 정리해 봐야겠다.
Today I Learned
클라이언트-서버 아키텍처
- 리소스를 사용하는 주체인 클라이언트(client)와 리소스를 제공하는 주체인 서버(server) 간에 작업을 분리한 네트워크 아키텍처. 2티어 아키텍처라고도 부른다. 대표적으로 World Wide Web이 있다.
- 클라이언트-서버에 리소스를 저장하는 공간인 데이터베이스가 더해진 구조를 3티어 아키텍처라고 한다. 프론트엔드는 사용자의 눈에 보이는 클라이언트측을. 백엔드는 사용자의 눈에 보이지 않는 서버와 데이터베이스측을 담당한다.
- 클라이언트도 컴퓨터고 서버도 컴퓨터다. 리소스를 사용하면 클라이언트가 되고 제공하면 서버가 된다. 따라서 어떤 경우에는 클라이언트였던 것이 다른 경우에는 서버가 될 수도 있다. 데이터베이스도 서버로 리소스를 제공하므로 일종의 서버라고 볼 수 있다.
- 클라이언트와 서버는 요청과 응답을 주고받는다. 먼저 클라이언트에서 서버로 요청이 이루어지면 서버에서 클라이언트로 응답을 보낸다. (cf. popup이나 alert 등은 HTTP 기반의 네트워크 통신이 아니라 자바스크립트 이벤트다.)
- 클라이언트의 종류 : 플랫폼에 따라 구분. 웹 앱, 스마트폰 앱, 데스크탑 앱
- 서버의 종류 : 기능에 따라 구분. 웹 서버, 파일 서버, 메일 서버, 데이터베이스 서버
- 장점 : 앱에서 사용할 정보가 자주 업데이트 될 경우 이를 앱 자체에 담기보다 분리하여 서버에서 제공하면 사용자가 설치된 앱 자체를 업데이트할 필요 없이 실시간으로 서버에서 변하는 정보를 앱에서 받아 사용할 수 있다.
브라우저의 작동 원리
브라우저
- 브라우저는 WWW을 사용하기위해 필요한 소프트웨어다. 브라우저의 주된 기능은 사용자가 원하는 리소스(HTML, CSS, 이미지 등)를 서버에 요청하고 W3C에서 정한 명세서에 따라 그것을 해석하여 화면에 표시하는 것이다.
URL/URI
IP 주소와 Port
DNS
- Domain Name
- 특정 사이트에 접근하기 위해 기억하기 어려운 IP 주소 대신 사용하는 주소. (예: 도메인 이름(naver.com) = IP 주소(
125.209.222.142
))
- 도메인 이름은 일정 기간 대여하여 사용한다.
- 브라우저 검색창에 IP 주소가 아닌 도메인 이름을 입력하면 해당 도메인 이름과 매칭된 IP 주소를 찾는 과정이 필요하다.
- DNS (Domian Name System)
- 도메인 이름을 IP 주소로 변환하거나 반대의 경우를 수행할 수 있도록 개발된 데이터베이스 시스템
- 브라우저 검색창에 도메인 주소를 입력하면 DNS에서 이와 매칭된 IP 주소를 찾고 이에 해당하는 웹 서버로 요청을 전달하여 통신할 수 있도록 한다.
HTTP
- HyperText Transfer Protocol
- HTML과 같은 문서를 전송하기 위한 애플리케이션 레이어 프로토콜
- 웹 브라우저와 웹 서버는 HTTP라는 프로토콜(통신 규약)로 요청과 응답을 보낸다. 이 때 주고받는 메시지를 HTTP 메시지라고 부른다.
- HTTP는 클라인언트나 서버의 상태를 확인하지 않는다. (stateless)
HTTP Messages
- HTTP 메시지에는 요청(request)과 응답(response) 두 가지 유형이 있다.
- HTTP 메시지를 직접 작성할 일은 거의 없다. 구성 파일, API, 기타 인터페이스에서 HTTP 메시지를 자동으로 완성한다.
- 요청/응답 메시지 모두 유사한 구조를 가진다.
- Start Line : 요청/응답의 상태. 항상 가장 첫 번째 줄에 위치.
- HTTP Headers : 요청 지정, 본문 설명
- 헤더와 본문을 구분하는 빈 줄이 있음
- Body : 요청/응답 관련 데이터
- Head : Start Line + HTTP Headers / Body : Payload(메타데이터를 제외한 전송 데이터)
HTTP Requests
Start Line
- 구조 :
헤더이름 : 값
- 헤더의 종류
- General Headers : 메시지 전체에 적용되는 헤더. body의 전송 데이터와는 관련 없음.
- Request Headers : 요청할 리소스나 클라이언트 자체에 대한 정보를 포함하는 헤더.
- Representation Headers (Entity Headers) : body에 담긴 리소스의 정보를 포함하는 헤더 (컨텐츠 길이, 타입 등). 요청 내에 body가 없는 경우 전송되지 않음.
Body
- HTTP 요청 메시지의 가장 마지막에 위치하며 항상 필요한 것은 아니다.
POST
나 PUT
같은 일부 요청에서 데이터를 업데이트하기 위해 사용된다.
- 바디의 종류
- 단일 리소스 본문 (Single-Resource Bodies) :
Content-type
과 Content-Length
헤더로 정의된 단일 파일로 구성
- 다중 리소스 본문 (Multiple-Resource Bodies) : 여러 파트로 구성된 본문. 각 파트마다 다른 정보를 가짐. 보통 HTML form과 관련됨.
HTTP Responses
Start Line (Status Line)
- 구조 :
프로토콜 버전
/ 상태 코드
/ 상태 텍스트
- HTTP Status Code
- 정보를 제공하는 응답 (
100
-199
)
- 성공적인 응답 (
200
-299
)
- 리다이렉트 (
300
-399
)
- 클라이언트 에러 (
400
-499
)
- 서버 에러 (
500
-599
)
- 요청 헤더와 동일한 구조를 가짐
- 헤더의 종류
- General Headers : 메시지 전체에 적용되는 헤더. body의 전송 데이터와는 관련 없음.
- Response Headers : 위치/서버 자체에 대한 정보. 상태 줄에 넣기에 공간이 부족했던 추가 정보 제공.
- Representational Headers (Entity Headers) : body에 담긴 리소스의 정보를 포함하는 헤더 (컨텐츠 길이, 타입 등).
Body
- HTTP 요청 메시지의 가장 마지막에 위치하며 항상 필요한 것은 아니다.
202(Accepted)
나 204(No Content)
같은 상태 코드를 가지는 응답에는 본문이 필요하지 않다.
- 바디의 종류
- 단일 리소스 본문 (Single-Resource Bodies) :
- 길이가 알려진 단일 파일 :
Content-type
과 Content-Length
헤더로 정의된 단일 파일로 구성
- 길이를 모르는 단일 파일 : Transfer-Encoding이
chunked
로 설정되어 있으며 파일은 chunk로 나뉘어 인코딩되어 있다.
- 다중 리소스 본문 (Multiple-Resource Bodies) : 여러 파트로 구성된 본문. 각 파트마다 다른 정보를 가짐.
SSR vs CSR
- SSR은 서버에서, CSR은 클라이언트에서 웹 페이지 렌더링이 일어난다.
SSR
- Server Side Rendering
- 웹 페이지를 서버에서 렌더링하고 브라우저에서 서버로 요청을 보내면 정해진 웹 페이지를 브라우저로 전송한다. 필요한 데이터가 데이터베이스에 있을 경우 서버에서 이를 가져와 웹 페이지를 완전히 렌더링 한 후 클라이언트로 보낸다.
- 브라우저에서 다른 경로로 이동할 때마다 서버는 새로 작업을 수행한다.
- SEO에 CSR보다 유리. 웹 페이지의 첫 화면 렌더링이 빠름.
CSR
- Client Side Rendering
- AJAX의 등장으로 골격만 서버에서 받은 후 원하는 대로 데이터를 받아 클라이언트에서 웹 페이지를 렌더링 할 수 있게 되었다.
- SSR과 반대로 클라이언트에서 웹 페이지를 렌더링한다. 브라우저에서 요청을 보내면 서버는 웹 페이지의 골격이 되는 단일 페이지와 JS파일을 클라이언트로 보낸다. 클라이언트는 전달받은 JS파일로 웹 페이지를 렌더링한다. 필요한 데이터가 데이터베이스에 있을 경우 클라이언트에서 API로 이를 가져와 렌더링해야 한다.
- 브라우저에서 다른 경로로 이동하면 서버에서 웹 페이지를 다시 받는 것이 아니라 브라우저가 요청한 경로에따라 페이지를 다시 렌더링 한다.
- 웹 페이지가 사용자와 상호작용이 많을 경우 CSR이 유리.
CORS
-
교차 출처 리소스 공유 (Cross-Origin Resource Sharing)
-
리소스를 요청하는 웹 사이트와 요청을 받는 서버의 출처(도메인, 하위 도메인, 포트, 프로토콜)가 서로 같으면 문제가 없지만, 서로 다를 경우 브라우저에서 보안상의 이유로 요청을 제한한다. 출처가 다른 리소스를 불러오려면 그 출처(서버)에서 CORS 헤더를 포함한 응답을 반환해야 한다.
-
Simple Request (단순 요청)
- 한 번에 요청과 응답을 주고 받음
- Simple Request는 다음 조건을 모두 충족해야 한다
- 다음 중 하나의 메서드 :
GET
, HEAD
, POST
- 유저 에이전트가 자동 설정한 헤더 외 수동 설정 가능한 헤더는 다음 헤더들 뿐 :
Accept
, Accept-Language
, Content-Language
, Content-Type
Content-Type
에는 다음 값들만 허용 : application/x-www-form-urlencoded
, multipart/form-data
, text/plain
- 요청에 사용된
XMLHttpRequestUplaod
객체에 이벤트 리스너가 등록되어 있지 않음.
- 요청에
ReadableStrea
객체가 사용되지 않음
-
Preflighted Request (사전 요청)
- simple request 외 나머지 요청
- 먼저 클라이언트에서 요청을 전송하면 서버에서 접근 권한에 대한 응답을 전송하고 허용될 시 원래 보내려던 요청을 전달하여 리소스를 서버에서 받는다.