http/네트워크 - 기초

2021. 10. 18. 19:31·SE Bootcamp 내용 정리

http/네트워크 intro

학습 목표

* 클라이언트-서버 콘셉트
- 클라이언트-서버 아키텍처
- HTTP를 이용한 클라이언트-서버 간 통신
- API의 개념

* 브라우저의 작동 원리
- 보이지 않는 곳의 통신:
    URL과 URI의 차이
    IP 주소와 PORT
    DNS와 IP 주소의 관계
    크롬 브라우저의 에러 메시지 이해하기

- 보이는 곳의 통신:
    AJAX의 개념
    SSR과 CSR의 차이
    CORS의 개념

* HTTP messages의 구조
- HTTP의 동작 방식
- HTTP requests와 responses
- HTTP 응답 메시지

* Chrome Network Tab 이해하기
- Chrome Network Tab 사용방법

* Self Guided Lessons(Advanced)
- How the internet works
- DNS

클라이언트-서버 아키텍쳐(Client Server Architecture)

클라이언트-서버 아키텍쳐 이해하기

11번가를 예로 들어 생각 해보자
11번가 앱에서 물건을 쇼핑하려면 새로운 상품에 대한 목록들을 어딘가에서 받아와야 함

 

만약에 인터넷이 연결되어 있지 않다면 이 앱이 정상 작동하지 않을 것이다
why? 상품에 대한 정보를 받아올 서버와의 통신이 되지 않기 때문

 

11번가와 같은 앱 내에서는 수많은 상품 목록들이 업데이트된다
→ 빈번한 데이터 업데이트가 이루어지는 경우,
리소스가 존재하는 곳(서버)와 리소스를 사용하는 앱(클라이언트)을 분리시키는 것이 유리

 

→ 서버: 상품 정보를 가지고 있음(리소스가 존재하는 곳)
→ 앱: 상품 정보를 조회(리소스를 사용)

클라이언트-서버 아키텍쳐

이처럼, 리소스가 존재하는 곳(서버)와 리소스를 사용하는 앱(클라이언트)을 분리시킨 것을 2-Tier 아키텍쳐 또는 클라이언트-서버 아키텍처

 

클라이언트-서버 간 관계는 요청과 응답으로 이루어 진다
→ 요청이 선행되고 응답이 그 후에 이루어진다

3Tier 아키텍쳐

클라이언트-서버 아키텍쳐에 데이터베이스가 추가된 형태
→ 일반적으로 많이 쓰는 case

* 앱(클라이언트): 리소스를 사용
* 서버: 리소스만 전달
* 데이터베이스: 리소스 저장 공간

프론트엔드와 백엔드

프론트엔드와 백엔드를 구분하는 기준이 아키텍쳐에서 어떤 분야를 다루는가에 따라 나뉜다

 

프론트엔드: 사용자의 눈에 보이는 부분을 다루는 영역
→ 주로, 사용자와 상호작용하는 UI 등 앱 개발 부분

 

백엔드: 사용자 눈에 직접적으로 보이지 않는 부분을 다루는 영역
→ 주로, 사용자 인증(권한 관리, 로그인), API 등 서버나 데이터베이스 설계 등의 영역

클라이언트와 서버의 종류

* 클라이언트: `플랫폼의 종류`에 따라 구분

- 웹(Web) 플랫폼 기반 앱(Web site)
- 스마트폰/태블릿 플랫폼 기반 앱
- 데스크탑 플랫폼 기반

* 서버: `용도`에 따라 구분

- 웹 서버: 웹 사이트에서 필요로 하는 정보를 제공
- 파일 서버: 파일을 제공
- 메일 서버: 메일을 주고 받을 수 있도록 도와주는 서버
- 데이터베이스 서버: 데이터(정보) 제공

HTTP를 이용한 클라이언트-서버 간 통신과 API

클라이언트 서버 간의 통신은 요청과 응답으로 구성된다
→ 요청이 있어야 응답이 온다는 것!

 

이 통신에서는 프로토콜(통신 규약)을 지켜야 한다
→ 웹 애플리케이션 아키텍쳐에서는 HTTP 라는 프로토콜을 이용해 클라이언트와 서버가 서로 대화를 나눈다

주요 프로토콜

OSI 7계층을 생각하면 된다

7계층: 응용(Application) 계층
- HTTP : 웹에서 HTML, JSON 등의 정보를 주고 받는 프로토콜
- HTTPS: HTTP에서 보안(Secure)이 강화된 프로토콜
- FTP: 파일 전송 프로토콜
- SMTP: 메일 전송 프로토콜
- SSH: CLI 환경의 원격 컴퓨터에게 접속하기 위한 프로토콜
- RDP: Windows 계열의 원격 컴퓨터에게 접속하기 위한 프로토콜
- WebSorket: 실시간 통신, Push 등을 지원하는 프로토콜

6계층: 표현 계층
5계층: 세션 계층
4계층: 전송 계층
- TCP: HTTP, FTP 통신의 근간의 되는 인터넷 프로토콜(양방향, 3hand-Shake)
- UDP: 단방향으로 작동하여 더 단순하고 빠르지만 신뢰성이 낮은 인터넷 프로토콜

3계층: 네트워크 계층
4계층: 데이터 링크
1계층: 물리

API(Application Programming Interface)

서버가 클라이언트에게 리소스를 잘 활용할 수 있도록 인터페이스를 제공해 주는 것
→ 서버가 클라이언트에게 마치, 식당에서 메뉴판을 제공하듯이, 리소스를 잘 활용할 수 있도록 API 문서를 제공해 주는 것
→ 보통 인터넷에 있는 데이터를 요청할 때는 HTTP 프로토클을 사용하며, 주소(URL, URI)를 통해 접근

 

ex) API의 예시: 피자 전문점

요청                    URL 디자인 예시
==============================================
콤비네이션 피자 주세요            /pizza/combination
파인애플 피자 주세요            /pizza/pineapple
콤비네이션 피자 2판 주세요        /pizza/combination?quantity=2
파인애플 피자 2판에 치즈 토핑 추가요!    /pizza/pineapple?quantity=2&topping=cheese
==============================================

HTTP Best Practice

HTTP API 디자인에는 Best Practice가 존재한다
→ HTTP 요청시 메소드를 지정하여 리소스와 관련된 행동(CRUD; Create/Read/Update/Delete)을 지정할 수 있다
→ CRUD의 각각의 행동에 일치하는 메소드들


요청            적절한 메소드
========================
조회(Read)        Get
추가(Create)        Post
갱신(Update)    Put 또는 Patch
삭제(Delete)        Delete
========================

웹 아키텍쳐에서의 클라이언트-서버 관계 정리

클라이언트는 인터넷에 연결된 사용자의 디바이스, 또는 웹에 접근할 수 있는 소프트웨어를 뜻한다. 대표적인 예로 [브라우저]가 있는데, [브라우저]는 HTML, CSS, JavaScript 등으로 작성된 코드를 내부 엔진으로 해독하여 사용자가 쉽게 이해할 수 있는 형태의 컨텐츠로 보여주는 역할을 한다.서버는 클라이언트가 어떤 자원을 요청하면 해당 요청을 적절하게 처리하는 역할을 한다. 클라이언트는 서버의 자원을 어떻게 사용할 수 있는지 명시해 둔 인터페이스 [API]에 따라 요청을 전송한다.이렇게 클라이언트와 서버가 서로 요청과 응답을 주고받을 수 있는 것은 [HTTP]라는 통신 규약 덕분이다.

브라우저의 작동 원리(보이지 않는 곳)

URL과 URI

브라우저 주소창에 입력한 URL은 서버가 제공되는 환경에 존재하는 파일의 위치를 나타냄

URL은 Uniform Resource Locator의 줄임말로, 네트워크 상에서 웹 페이지, 이미지, 동영상 등의 파일이 위치한 정보를 나타냅니다. URL은 scheme, hosts, url-path로 구분할 수 있습니다. 가장 먼저 작성하는 scheme은 통신 방식(프로토콜)을 결정합니다. 일반적인 웹 브라우저에서는 http(s)를 사용합니다. hosts는 웹 서버의 이름이나 도메인, IP를 사용하며 주소를 나타냅니다. url-path는 웹 서버에서 지정한 루트 디렉토리부터 시작하여 웹 페이지, 이미지, 동영상 등이 위치한 경로와 파일명을 나타냅니다.

 

브라우저의 검색창을 클릭하면 나타나는 주소가 URI

URI는 Uniform Resource Identifier의 줄임말로, 일반적으로 URL의 기본 요소인 scheme, hosts, url-path에 더해 query, bookmark를 포함합니다. query는 웹 서버에 보내는 추가적인 질문입니다. http://www.google.com:80/search?q=JavaScript 를 브라우저의 검색창에 입력하면, 구글에서 JavaScript를 검색한 결과가 나타납니다.

→ URI은 URL을 포함하는 상위 개념
(그러므로, URL은 URI다 (o), URI는 URL이다(x))

 

부분                명칭            설명
==============================================
file://, http://        scheme        통신 프로토콜
www.google.com        hosts            파일이 위치한 웹 서버, 도메인 또는 IP
:443, :3000            port            웹 서버에 접근하기 위한 통로
/search/blabla        url-path        웹 서버의 루트 디렉토리부터 해당 파일까지의 경로
q=JavaScript        query            웹 서버에 전달하는 추가 질문
==============================================

URL과 URI의 구성요소

URL: scheme(ex. https://), hosts(ex. www.google.com), url-path(ex. Search)
→ 프로토콜(scheme), 호스트(도메인), 포트번호 라고 봐도 된다?

 

URI: URL+query(ex. ?q=JavaScript), bookmark(ex. #section1)

→ URI는 URL의 구성요소를 모두 포함하고 거기에 쿼리, 북마크 등이 추가될 수 있다

 

IP와 포트

IP address

IP: Internet Protocol의 줄임말. 인터넷 상에서 사용하는 주소 체계
IPv4: 4덩이의 숫자로 구분
IPv6: 6덩이 숫자

localhost 또는 127.0.0.1 : 현재 자신의 로컬 Pc를 지칭

0.0.0.0 또는 255.255.255.255: 브로드캐스트 주소로, 로컬 네트워크에 접속된 모든 장치와 소통하는 주소. 
서버에서 접근 가능 IP 주소를 브로드캐스트 주소로 지정하면 모든 기기에서 서버에 접근 가능

PORT

IP가 가리키는 PC에 접속할 수 있는 통로(채널)

 

포트번호는 0~65535 까지 사용 가능

 

0~1024번까지 포트 번호는 주요 통신 규약으로 정해진 well-known port

22: SSH
80: HTTP
443: HTTPS

도메인과 DNS(Domain Name System)

Domain name

IP 주소를 대신하여 사용하는 주소

터미널 창에서 도메인 이름을 통해 IP 주소를 확인하는 명령어 nslookup으로 IP 주소 확인 가능

ex) 142.250.66.110 → google.com

DNS(Domain Name System)

네트워크 상에 존재하는 모든 PC는 IP가 있지만 도메인 이름을 모두 가지는 것은 아님
→ 도메인 이름을 일정 기간 동안 대여해서 사용하는 것(ex. 웹 사이트들)

 

대여한 도메인 이름과 IP 주소를 매칭할 때, 해당 도메인 이름과 매칭된 IP 주소를 확인하는 작업이 필요
→ DNS가 그 역할을 수행해 줌
→ 호스트의 도메인 이름을 IP 주소로 변환하거나 그 반대의 경우를 수행할 수 있도록 개발된 데이터베이스 시스템(ex. 구글의 8.8.8.8)

 

도메인 주소는 가장 왼쪽부터 오른쪽으로 서브 도메인(Sub Domain), 루트 도메인(Root Domain), 최상위 도메인(Top Level Domain)으로 구성되어 있다

<도메인 네임>

sub-domain.Root-domain.TLD

ex) https://www.    google.    com

 

도메인을 관리하는 서버(존)은 다음 3가지로 나뉜다

<도메인 네임 시스템; DNS>

* Root 네임 서버: 모든 도메인을 관리하는 서버
- 각 최상위 도메인 네임 서버들의 주소를 알고 있다.

* TLD(최상위 도메인) 네임 서버: TLD 네임을 관리하는 서버
- 권한있는 네임 서버의 주소를 알고 있다

* 권한 있는 네임 서버: 도메인 IP 주소 및 도메인 정보를 관리하는 권한을 가진 서버

도메인 네임 서버 중 권한 있는 네임 서버는 IP 주소 및 도메인 정보를 관리하는 권한을 가지고 있다

 

DNS Lookup을 하는 경우, 브라우저 단의 resolver(리졸버)가 루트 도메인, 최상위 도메인, 권한 있는 도메인 서버 순으로 쿼리를 진행하며, IP 주소를 알아 낸다. 이는 재귀적으로 처리된다

 

DNS 요청이 HTTP 요청보다 우선하여 처리(요청→ 응답)되고, 그 후에 HTTP 요청이 처리된다(요청→ 응답)

 

크롬 브라우저 에러 읽기

chrome 브라우저를 사용하다가 만나게 되는 에러 메시지들


ex) 각종 에러 메시지의 몇가지 예시들

Error Message                    설명
=============================================
“Aw.Snap!”(앗, 이런!)        크롬 브라우저에서 페이지를 로드하는 데 문제가 발생
ERR_NAME_NOT_RESOLVED    호스트 이름(웹 주소)가  존재하지 않음
ERR_CONNECTION_RESET    웹페이지 연결을 방해하는 요소가 어딘가에 발생함
ERR_CONNECTION_REFUSED    웹페이지에서 크롬 브라우저의 연결을 허용하지 않음
ERR_CACHE_MISS        웹페이지로부터 이전에 입력한 정보를 다시 한번 제출하도록 요청받음
ERR_EMPTY_RESPONSE        웹페이지에서 데이터를 전송하지 않았으며, 서버가 다운됐을 수 있음
ERR_SSL_PROTOCOL_ERROR    페이지에서 전송된 데이터를 크롬 브라우저가 해석하지 못함
=============================================

전체 에러 메시지 목록은 chrome://network-errors 에서 확인 가능

 

Chrome Network Tab

Chrome Network Tab 사용 방법

(f12) 네트워크 패널은 열려있는 동안만 그 활동을 표시

 

속도 조절을 통해서 스마트폰과 같은 환경에서의 화면 로딩 속도등을 테스트 가능
→ 기본: disabled(No throttling) → 원하는 속도로 변경 조절

 

특정 파일 차단 제어: ctrl+shift+P: block 명령어 입력 후

 

패턴에 원하는 제어할 파일 추가 후 새로고침하면 해당 파일만 blocking 되어 로딩됨을 알 수 있다
→ 특정 파일과 관련하여 이슈나 확인 등에 용도에서 좋음

HTTP

HTTP Messages

HTTP; Hyper Text Transfer Procotol. HTML과 같은 문서를 전송하기 위한 응용 계층(7) Protocol이다

 

클라이언트가 HTTP message 양식에 맞춰 요청을 보내면 서버가 HTTP message 양식에 맞춰 응답하는 것이 기본 클라이언트-서버 모델의 형태

 

HTTP는 특정 상태를 유지하지 않는다는 특징이 존재

* HTTP의 특징: 무상태성(Stateless)

 

HTTP messages 에는 다음의 2가지 유형이 있다

* 요청(request)
* 응답(response)

 

보통, 구성 파일, API, 기타 인터페이스에서 HTTP message를 자동으로 완성하므로 개발자가 직접 작성할 필요는 거의 없다

 

HTTP 요청과 응답의 구조는 서로 닮았으며, 그 구조는 다음과 같다


* 1. start line: 요청이나 응답의 상태를 나타냄. 항상 첫번째 줄에 위치. 
응답에서는 status line이라고 부름 
→ 이 줄은 항상 한줄로 끝난다.

* 2. HTTP headers(옵션; 선택적): 요청에 대한 설명, 혹은 메시지의 포함된 본문을 설명하는 헤더의 집합

* 3. empty line: 헤더와 본문을 구분하는 빈 줄

* 4. body: 요청과 관련된 데이터(HTML 폼 콘텐츠 등)나 응답과 관련된 데이터 또는 문서(document)가 들어감.
본문의 존재 유무 및 크기는 첫줄과 HTTP 헤더에 명시되며, 요청과 응답의 유형에 따라 선택적으로 사용

→ start line과 HTTP headers를 묶어 헤드(head)라고 하고, payload(전송되는 데이터)를 body라 한다

HTTP 요청(request)

start line

HTTP 요청은 클라이언트가 서버에 보내는 메시지
start line에는 3가지 요소가 있다

1. 수행할 작업(GET, PUT, POST 등)이나 방식(HEAD or OPTIONS)을 설명하는 `HTTP method`
→ 예를 들어 GET method는 리소스를 받고, POST method는 데이터를 서버로 전송

2. `요청 타겟`: 요청 타겟은 주로 URL, 또는 프로토콜, 포트, 도메인의 절대 경로로 나타낼 수도 있으며 
이들은 요청 컨텍스트에 의해 특정지어 진다. 요청 타겟 포맷은 HTTP 메소드에 따라 달라지는데 
포맷은 아래 와 같다

- origin 형식 : 끝에 `?`와 쿼리 문자열이 붙는 절대 경로. 
가장 일반적인 방식으로 POST, GET, HEAD, OPTIONS 등의 method와 함께 사용

    POST / HTTP 1.1
    GET /background.png HTTP/1.0
    HEAD /test.html?query=alibaba HTTP/1.1
    OPTIONS /anypage.html HTTP/1.0

- absolute 형식 : 완전한 URL 형식으로, 프록시에 연결하는 경우 대부분 GET method와 함께 사용

    GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1

- authority 형식 : 도메인 이름과 포트 번호로 이루어진 URL의 authority component. 
HTTP 터널을 구축하는 경우에만, CONNECT와 함께 사용할 수 있다

    CONNECT developer.mozilla.org:80 HTTP/1.1

- asterisk 형식 : OPTIONS 와 함께 별표(*) 하나로 간단하게 서버 전체를 표현
    OPTIONS * HTTP/1.1

3. `HTTP 버전` : 버전에 따라 HTTP message의 구조가 달라진다
→ start line에 버전을 함께 입력한다

headers

기본 구조는 다음과 같다

헤더이름(대소문자 구분이 없는 문자열):값


ex)

Host: localhost:8000        /request headers
User-Agent: Firefox/51.0    //request headers

…
Connection: keep-alive        //general headers
Content-type: multipart/form-data; blabla    //Entity headers
Content-length: 345        //Entity headers
...

 

여러 종류의 헤더가 존재하는데 다음과 같이 분류할 수 있다

* general headers: 메시지 전체에 적용되는 헤더로, body를 통해 전송되는 데이터와는 관련이 없는 헤더

* request headers: fetch를 통해 가져올 리소스나 클라이언트 자체에 대한 자세한 정보를 포함하는 헤더
→ User-Agent (en-US), Accept-Type와 같은 헤더는 
요청의 내용을 좀 더 구체화 시키고(Accept-Language), 컨텍스를 제공하기도 하며(Referer), 
조건에 따른 제약 사항을 가하기도 하면서(If-None) 요청 내용을 수정한다

* representation headers: entity header라고도 하며, 
body에 담긴 리소스의 정보(컨텐츠 길이, MIME 타입 등)를 포함하는 헤더
→ 본문이 없는 경우 해당 헤더는 전송되지 않는다

body

요청의 본문으로 HTTP message 구조의 마지막에 위치
모든 요청에 body가 필요하진 않다→ 삭제(D; delete)나 읽기(R; get)같은 경우 본문이 필요없으니깐

 

body는 다음의 2가지 종류로 구분 가능하다

* single-resource bodies(단일-리소스 본문): 헤더 두 개(Content-Type과 Content-Length)로 정의된 
단일 파일로 구성

* multiple-resource bodies(다중-리소스 본문): 여러 파트로 구성된 본문으로, 
각 파트마다 다른 정보를 가지고 있음. 보통 HTML form과 연관

 

이를 종합해서 살펴 보면 HTTP request(요청)은 아래와 같은 형태를 가진다

<HTTP 요청>

start line
---------------

optional request    // 선택적 요청 헤더
headers        // start line+headers = header

---------------
빈 줄(blank line)
---------------

body(optional)

HTTP 응답(response)

status line(상태 줄)

응답에서의 start line을 지칭하고 다음의 정보를 포함

1. 현재 프로토콜의 버전(ex. HTTP/1.1)

2. 상태 코드
-요청의 결과를 나타냄(ex. 404, 200)

3. 상태 텍스트
- 상태 코드에 대한  설명(ex. Not Found)

→ 종합하면 `HTTP/1.1 404 Not Found` 의 형태

headers

요청 헤더와 동일한 구조로 되어 있다.

* general headers: 내용 동일

* response headers: 위치 또는 서버 자체에 대한 정보(이름, 버전 등)와 같이 
응답에 대한 부가적인 정보를 갖는 헤더로, Vary, Accept-Ranges와 같이 상태 줄에 넣기에는 
공간이 부족했던 추가 정보를 제공

* representation headers: 내용 동일

body

모든 응답에 body가 필요하지는 않다
→ 201, 204 상태코드의 응답에는 본문이 필요없으므로

 

응답의 body는 마찬가지로 2종류로 나뉜다


* single-resource bodies(단일-리소스 본문): 요청과 동일한 구조

* multiple-resource bodies(다중-리소스 본문): 요청과 동일하게 각 파트마다 서로 다른 정보를 담고 있음

 

이를 종합해서 살펴보면 HTTP response(응답)은 다음과 같은 형태를 가진다

<HTTP 응답>

status line
---------------
optional response
headers            //status line+headers = header

---------------
빈 줄
---------------

body(optional);
requested response(요청된 응답)

stateless(무상태성)

말 그대로 상태를 가지지 않는다는 뜻

HTTP는 통신 규약일 뿐, HTTP가 클라이언트-서버 통신 간에 상태를 확인한다든지, 상태를 추적한다든지, 특정 상태를 저장한다든지 하지 않는다!

→ 무상태성(stateless)이 HTTP의 큰 특징

추가적으로 알아야 할 내용

HTTP 요청 메서드

HTTP는 요청 메서드를 정의하여, 주어진 리소스에 수행하길 원하는 행동을 나타낸다

* GET
특정 리소스의 표시(읽기)를 요청
→ 오직 데이터를 받기만 한다

* HEAD
GET 메서드의 요청과 동일한 응답을 요구하지만, 응답 본문은 요구하지 않는다

* POST
특정 리소스에 엔티티를 제출(주로 Create)할 때 쓴다
→ 서버 상태의 변화나 부작용을 일으킬 수 있다


* PUT
목적 리소스의 모든 현재 표시를 요청 payload(전송되는 데이터)로 바꾼다

* DELETE
특정 리소스를 삭제

* CONNECT
목적 리소스인 서버로의 터널을 맺음(통신 연결)

* OPTIONS
목적 리소스의 통신을 설정하는데 사용

* TRACE
목적 리소스의 경로를 따라서 loop-back 테스트를 실행

* PATCH
리소스의 일부분을 수정하는 데 사용

HTTP 메서드의 멱등성(idempotent)

동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말합니다. 다른 말로는, 멱등성 메서드에는 통계 기록 등을 제외하면 어떠한 부수 효과(side effect)도 존재해서는 안됩니다. 올바르게 구현한 경우 GET, HEAD, PUT, DELETE 메서드는 멱등성을 가지며, POST 메서드는 그렇지 않습니다. 모든 안전한 메서드는 멱등성도 가집니다

HTTP 상태 코드(HTTP Status Code)

HTTP 응답 상태 코드는 특정 HTTP 요청이 성공적으로 완료되었는지 알려줍니다. 응답은 5개의 그룹으로 나누어집니다: 1.정보를 제공하는 응답, 2. 성공적인 응답, 3. 리다이렉트, 4. 클라이언트 에러, 그리고 5. 서버 에러

대표적인 몇가지 상태 코드

* 200 OK
요청이 성공적으로 되었다는 의미

* 201 Created
요청이 성공적이었으며 그 결과로 새로운 리소스가 생성됨. 이 응답은 일반적으로 POST 요청 또는 
일부 PUT 요청 이후에 따라온다

* 400 Bad request
이 응답은 잘못된 문법으로 인하여 서버가 요청을 이해할 수 없음을 의미

* 401 Unauthorized
비록 HTTP 표준에서는 "미승인(unauthorized)"를 명확히 하고 있지만, 의미상 이 응답은 
"비인증(unauthenticated)"을 의미한다. 클라이언트는 요청한 응답을 받기 위해서는 
반드시 스스로를 인증해야 한다

* 403 Forbidden
클라이언트는 콘텐츠에 접근할 권리를 가지고 있지 않음을 뜻함. 
예를들어 그들은 미승인이어서 서버는 거절을 위한 적절한 응답을 보낸다. 
401과 다른 점은 서버가 클라이언트가 누구인지 알고 있다

* 404 Not Found
"서버는 요청받은 리소스를 찾을 수 없습니다. 브라우저에서는 알려지지 않은 URL을 의미합니다. 
이것은 API에서 종점은 적절하지만 리소스 자체는 존재하지 않음을 의미할 수도 있습니다. 
서버들은 인증받지 않은 클라이언트로부터 리소스를 숨기기 위하여 이 응답을 403 대신에 전송할 수도 있습니다. 
이 응답 코드는 웹에서 반복적으로 발생하기 때문에 가장 유명하다"

 

이외에도 아주 많은데, 대강의 무드(느낌적인 느낌?)만 알면 된다

 

크게 5가지 그룹으로 나뉘니깐!
→ 정보를 제공하는 응답, 성공적인 응답, 리다이렉트, 클라이언트 에러, 서버 에러

1xx: hold on; 기다려(참아) → (기다리라는) 정보를 제공하는 응답
2xx: here you go;자 (니가 원한거) 여기 있어 → 성공적인 응답(니가 요청한거 되었다는)
3xx: go away; 사라졌다(니가 보낸거)→ 다시 보내셈 → 리다이렉트
4xx: you screwed up; 니(클라이언트)가 맛 간거야 → 클라이언트 에러
5xx: I screwed up; 내(서버)가 맛이 갔네 → 서버 에러

브라우저의 작동 원리(보이는 곳)

SPA를 만드는 기술 : AJAX

웹 페이지에서 일부분만 바꾸고 싶은 경우에 사용하는 기술

AJAX란?

Asynchronous JavaScript And XMLHttpRequest의 약자
→ JavaScript, DOM, Fetch, XMLHttpRequest, HTML 등의 다양한 기술을 사용하는 웹 개발 기법
→ 웹 페이지의 필요한 부분에 필요한 데이터만 비동기적으로 받아와 화면에 그려낼 수 있다는 특징!

 

구글 검색 페이지를 생각!
→ 웹 페이지에 html에 의해서 페이지가 렌더링되지만 딱 한 군데, 검색창 만큼은 html에 작성된 대로 사용자가 사용하는 것이 아닌, 사용자의 요구에 따라 반응하며 변화한다
→ 검색창에서는 필요한 데이터만 비동기적으로 받아와 렌더링되며, 여기에 AJAX가 사용되는 것!

 

이 외에도, 네이버 의 뉴스 탭, 페이스북 메시지 등도 AJAX 기법을 사용한 예

AJAX의 2가지 핵심 기술

JavaScript와 DOM, 그리고 Fetch가 그 핵심 기술

 

Fetch를 사용하면, 페이지를 이동하지 않아도 서버로부터 필요한 데이터를 받아올 수 있다
Fetch는 사용자가 현재 페이지에서 작업을 하는 동안 서버와 통신할 수 있도록 한다

 

→ 브라우저는 Fetch가 서버에 요청을 보내고 응답을 받을때까지 모든 동작을 멈추는 것이 아니라, 계속해서 페이지를 사용할 수 있게 하는 비동기적인 방식을 사용한다

 

→ 또한 자바스크립트에서 DOM을 사용해 조작할 수 있기 때문에, Fetch를 통해 전체 페이지가 아닌 필요한 데이터만 가져와 DOM에 적용시켜 새로운 페이지로 이동하지 않고 기존 페이지에서 필요한 부분만 변경할 수 있다

XHR과 Fetch

Fetch 이전에 사용한 방식이 XHR(XMLHttpRequest)
→ AJAX 도입 전에는 XMLHttpRequest를 사용했는데 이 것은 동적 렌더링을 해주지만 효율이 떨어졋다는 것 (정적은 x)
→ Fetch가 XHR의 단점을 보완한 새로운 웹 API이며, XHR보다 가볍고 JavaScript와 호환되는 JSON을 사용한다

ex) Fetch 예제


fetch('http://52.78.213.9:3000/messages')
    .then (function(response) {
        return response.json();
    })
    .then(function (json) {
        ...
});


ex) XHR의 예제

// XMLHttpRequest를 사용
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://52.78.213.9:3000/messages');

xhr.onreadystatechange = function(){
    if(xhr.readyState !== 4) return;
    // readyState 4: 완료

    if(xhr.status === 200) {
        // status 200: 성공
        console.log(xhr.responseText); // 서버로부터 온 응답
    } else {
        console.log('에러: ' + xhr.status); // 요청 도중 에러 발생
    }
}

xhr.send(); // 요청 전송

 

AJAX의 장점

* 미완성된 HTML로도 화면 렌더링(웹 페이지 출력) 가능: 
서버에서 HTML을 완성하여 보내주지 않아도 웹페이지를 만들 수 있다. 
AJAX를 사용하면 서버에서 완성된 HTML을 보내주지 않아도 필요한 데이터를 비동기적으로 가져와 
브라우저에서 화면의 일부만 업데이트 하여 렌더링 할 수 있다

* 브라우저 호환성: 표준화된 방법 이전에는 브라우저마다 다른 방식으로 AJAX를 사용했으나, 
XHR이 표준화 되면서부터 브라우저에 상관 없이AJAX를 사용할 수 있게 됨

* 높은 상호작용성: 유저 중심 어플리케이션 개발  AJAX를 사용하면 필요한 일부분만 렌더링하기 때문에 
빠르고 더 많은 상호작용이 가능한 어플리케이션을 개발 가능

* 더 작은 대역폭 사용: 이전에는 서버로부터 완성된 HTML 파일을 받아와야했기 때문에 
한번에 보내야 하는 데이터의 크기(대역폭)가 컸음. 
그러나 AJAX에서는 필요한 데이터를 텍스트 형태(JSON, XML 등) 보내면 되기 때문에 비교적 데이터의 크기가 작다

 

AJAX의 단점

* Search Engine Optimization(SEO;검색 엔진 최적화)에 불리: 
AJAX 방식의 웹 어플리케이션은 한 번 받은 HTML을 렌더링 한 후, 
서버에서 비동기적으로 필요한 데이터를 가져와 그려낸다
→ 따라서, 처음 받는 HTML 파일에는 데이터를 채우기 위한 틀만 작성되어 있는 경우가 많음

검색 사이트에서는 전세계 사이트를 돌아다니며 각 사이트의 모든 정보를 긁어와, 
사용자에게 검색 결과로 보여주는데, AJAX 방식의 웹 어플리케이션의 HTML 파일은 
뼈대만 있고 데이터는 없기 때문에 사이트의 정보를 긁어가기 어렵다

* 뒤로가기 버튼 문제: 
AJAX에서는 이전 상태를 기억하지 않기 때문에 사용자가 의도한 대로 동작하지 않습니다(뒤로가기 불가). 
따라서 뒤로가기 등의 기능을 구현하기 위해서는 별도로 History API를 사용해야 한다

SSR과 CSR

SSR과 CSR(Client Side Rendering)의 차이점을 아는 것이 중요!

SSR

SSR은 Server Side Rendering의 약어
→ 웹 페이지를 브라우저에서 렌더링하는 대신에, 서버에서 렌더링

 

브라우저가 서버의 URI로 GET 요청을 보내면, 서버는 정해진 웹 페이지 파일을 브라우저로 전송한다
그리고 서버의 웹 페이지가 브라우저에 도착하면 완전히 렌더링되는 구조
→ 서버에서 웹 페이지를 브라우저로 보내기 전에, 서버에서 완전히 렌더링했기 때문에 Server Side Rendering 이라고 함

 

사용자가 브라우저의 다른 경로로 이동할 때마다 서버는 이 작업을 다시 수행한다는 특징(단점?)

CSR

CSR은 Client Side Rendering 을 뜻함
→ SSR이 서버 측에서 페이지를 렌더링한다면, CSR은 클라이언트에서 페이지를 렌더링

 

웹 개발에서 사용하는 대표적인 클라이언트는 웹 브라우저

 

브라우저의 요청을 서버로 보내면 서버는 웹 페이지를 렌더링하는 대신, 웹 페이지의 골격이 될 단일 페이지 를 클라이언트에 전달하는데, 이때 서버는 웹 페이지와 함께 JavaScript 파일을 전달
→ 전달된 JavaScript 파일은 브라우저에서 웹 페이지를 완전히 렌더링 된 페이지로 바꾸도록 동작한다

 

웹 페이지에 필요한 내용이 데이터베이스에 저장된 데이터인 경우에는 API를 사용하여 브라우저가 데이터를 가져와 렌더링 한다

 

브라우저의 다른 경로로 이동할 때마다 서버가 웹페이지를 다시 보내지 않고, 브라우저가 요청 경로에 따라 페이지를 다시 렌더링하는데, 이때 출력되는 웹 페이지의 파일은 맨 처음 서버로부터 전달 받은 웹 페이지의 파일과 동일한 파일이다(sigle page 라는 뜻?)

 

CSR에서 서버의 역할

서버는 주로 API의 응답을 담당함

SSR과 CSR의 차이

주요 차이점은 페이지가 렌더링되는 위치!

* SSR: `서버`에서 페이지를 렌더링

* CSR: `브라우저(클라이언트)`에서 페이지를 렌더링
→ 브라우저는 사용자가 다른 경로를 요청할 때마다 페이지를 새로고침 하지 않고, 동적으로 라우팅 관리

어느게 한쪽이 낫다라는 개념은 아니다.
SSR이 기존에 사용되고 있었는데, AJAX의 등장으로 CSR이 부상함.
그런데 SEO 최적화가 어려움 등의 단점으로 인해 SSR을 쓰거나, 요새는 두개를 섞어서 쓰는 방식도 쓰기도 함

SSR을 사용하는 case

  • 검색 엔진 최적화(SEO; Search Engine Optimization)가 우선순위인 경우
  • 빠른 웹 페이지 첫 화면 렌더링이 필요한 경우(작은 단일 파일의 SSR 사용)
  • 웹 페이지와 사용자 간 상호 작용이 적은 경우

CSR을 사용하는 case

  • 검색 엔진 최적화(SEO)가 우선순위가 아닌 경우
  • 사이트에 풍부한 상호 작용이 있는 경우(CSR의 빠른 라우팅 → 높은 사용자 경험 제공)
  • 웹 애플리케이션 제작하는 경우

Browser Security Model

브라우저 보안과 관련된 부분

CORS(Cross-Origin Resource Sharing): 교차 출처 리소스 공유

서로 다른 오리진(출처) 간 리소스를 공유하는 메커니즘같은 것
→ 추가 HTTP 헤더를 사용하여 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제. 웹 애플리케이션은 리소스가 자신의 출처와 다를 때 교차 출처 HTTP 요청을 실행 한다

 

일반적으로 보안 상의 이유로 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한 한다
이는 브라우저가 자발적으로 브라우저를 사용하는 유저들을 보호하기 위한 정책임
→ 어플리케이션을 보호하는 목적이 아니라 사용자를 보호하기 위한 브라우저의 자발적인 보안 조치!

 

다른 출처의 리소스를 불러오려면, 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 함
→ CORS 표준에 맞춰야 한다는 뜻!

 

Simple request(단순 요청)

단순 요청이 되려면 다음의 모든 조건을 충족해야 함(and)

* 다음 중 하나의 메서드: GET, HEAD, POST
* 유저 에이전트가 자동으로 설정하지 않은 헤더: 기본 제공 헤더(Accept, Content-Language 같은거)
* Content-Type 헤더는 다음 값만 가능:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
 등...

 

예를들어, `https://foo.example` 의 웹 컨텐츠가 `https://bar.other` 도메인의 컨텐츠를 호출하길 원합니다. foo.example에 배포된 자바스크립트에는 아래와 같은 코드가 사용될 수 있습니다.

const xhr = new XMLHttpRequest();
const url = 'https://bar.other/resources/public-data/';    // 다른 오리진을 요청

xhr.open('GET', url);
xhr.onreadystatechange = someHandler;
xhr.send();

 

이 내용을 HTTP 메시지로 확인해 보면 다음과 같다

ex) HTTP 요청(request)의 header 부분

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
__Origin: https://foo.example__

요청 헤더의 origin을 보면 https://foo.example로부터 요청이 왔다는 것을 알 수 있다

 

이제 서버쪽의 응답(reponse)를 살펴 보면,

ex) HTTP 응답(response)

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[…XML Data…]

서버는 Access-Control-Allow-Origin: *으로 응답했는데 이는 모든 도메인에서 접근할 수 있음을 의미

 

만약, `https://bar.other` 의 리소스 소유자가 오직 `https://foo.example` 의 요청만 리소스에 대한 접근을 허용하려는 경우 다음을 전송

Access-Control-Allow-Origin: https://foo.example

 

참고: 클라이언트는 서버가 어떤 origin의 요청을 허용하는지 알 수 없다
→ 서버로부터 받은 Access-Control-Allow-Origin 헤더 속성을 통해 접속 가능 여부만 확인 가능

프리플라이트(미리 전송) 요청

단순 요청이 아닌 경우, 대부분이 프리플라이트 요청이라고 보면 된다.

먼저 OPTIONS 메서드를 통해 다른 도메인의 리소스로 HTTP 요청을 보내 실제 요청이 전송하기에 안전한지 확인합니다. Cross-site 요청은 유저 데이터에 영향을 줄 수 있기 때문에 이와같이 미리 전송(preflighted)합니다.

ex) 프리플라이트 요청의 예제

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://bar.other/resources/post-here/');    //다른 출처에 대한 요청
xhr.setRequestHeader('Ping-Other', 'pingpong');    //커스터마이징한 헤더 실행
xhr.setRequestHeader('Content-Type', 'application/xml');    //단순 요청에 해당하지 않는 컨텐츠 타입
xhr.onreadystatechange = handler;
xhr.send('<person><name>Arun</name></person>');

→ POST 요청이 가기 전에 OPTIONS request가 먼저 간다!(프리플라이트 요청!)
여기서 서버가 해도 된다고 응답 주면(200 OK!), 그 다음에 POST 요청과 응답이 이루어 지는 것!

 

인증정보를 포함한 요청

서버에서 클라이언트(브라우저)에 쿠키(세션 토큰)를 심는 경우

 

쿠키 있는 정보를 같이 보낼거냐 했을 때의 request
→ 쿠키 있는 게 항상 요청(request)에 따라간다는 게 핵심이다 정도?

 

참고: https://developer.mozilla.org/ko/docs/Web/HTTP/CORS


저작자표시 (새창열림)

'SE Bootcamp 내용 정리' 카테고리의 다른 글

react - 데이터 흐름의 이해와 비동기 요청 처리 1  (0) 2021.10.21
http/네트워크 – REST API & Postman  (0) 2021.10.19
js/node - 비동기 2  (0) 2021.10.15
js/node - 비동기 1  (0) 2021.10.15
자료구조/알고리즘 - 자료구조 기초 2(Graph, Tree Search Algorithm)  (0) 2021.10.13
'SE Bootcamp 내용 정리' 카테고리의 다른 글
  • react - 데이터 흐름의 이해와 비동기 요청 처리 1
  • http/네트워크 – REST API & Postman
  • js/node - 비동기 2
  • js/node - 비동기 1
레실이
레실이
  • 레실이
    레실이의 티스토리
    레실이
  • 전체
    오늘
    어제
    • 분류 전체보기 (88)
      • SE Bootcamp 내용 정리 (63)
      • 알고리즘 연습 (7)
      • Project 주저리 (4)
      • 기술 면접 source (3)
      • 개발 일상 (9)
      • 생성 AI 활용 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    state
    JavaScript
    JS
    알고리즘
    데이터베이스
    useState
    문자열
    DOM
    MVC
    IT
    useRef
    객체
    중복 순열
    CORS
    ORM
    PickAndDrink
    node
    CSR
    node.js
    promise
    ubuntu
    CSS
    인증/보안
    Python
    mongoDB
    Linux
    Ajax
    자료구조
    fastapi
    react
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
레실이
http/네트워크 - 기초
상단으로

티스토리툴바