React - 서버와 통신
서버와 통신
※이 포스트에서는 Axios의 사용 없이, Fetch와 FormData만을 이용하여 구현하였습니다
REST API
정의
- 두 컴퓨터가 인터넷을 통해서 정보를 교환하기 위해 사용하는 통신 방식(인터페이스)
REST란?
- Representational State Transfer의 약자로, 네트워크에서 데이터의 전송 / 처리를 정의한 소프트웨어 아키텍처를 의미한다.
- 이를 이용하여, 대규모의 시스템 / 다중 플랫폼에서도 안정적인 통신의 구현 및 수정이 가능하다.
이점
확장성
- REST가 클라이언트 - 서버 간의 상호 작용을 담당하므로, 성능 향상 및 확장성에서 이점을 제공한다.
유연성
- RESTful 서비스는 완전한 클라이언트 - 서버간의 분리를 지원하여, 서버에서의 플랫폼 / 기술 변경이 클라이언트에 영향을 주지 않는다는 유연성을 제공한다.
- 서버 - 클라이언트 사이의 완전한 분리는 애플리케이션의 수정 없이도 DB 계층 변경 등을 가능하게 한다.
독립성
- REST API는 사용되는 기술과는 독립적으로 작동되어, 각종 프로그래밍 언어로 애플리케이션의 구현이 가능하며, 통신에 영향 없이 기술의 변경이 가능하다.
구성
고유 리소스 식별자
- 각 리소스를 고유하게 식별하기 위하여 URL을 사용함
- 예시) http://testsite.com/posts/post1
메소드
종류
- GET
- 데이터를 서버로 부터 받아올 때 사용
- 예시) 로그인 및 포스트 정보 가져오기
- POST
- 서버에 새로운 데이터를 추가할 때 사용
- 예시) 회원가입 및 새로운 글 작성
- PUT
- 기존에 존재하는 데이터를 변경할 때 사용
- 예시) 유저 데이터 변경, 글 수정
- DELETE
- 서버에 존재하는 데이터를 삭제할 때 사용
- 예시) 회원 탈퇴 및 글 / 댓글의 삭제
HTTP 헤더
- HTTP 메소드가 작동하기 위한 데이터
- 요청 방식, 인증 정보, 콘텐츠 타입 등의 정보를 포함하고 있다.
파라미터
- 경로 파라미터(URL)
- 리소스에 대한 추가 정보를 요청하는 쿼리 파라미터
- 클라이언트를 빠르게 인증하는 쿠키 파라미터
응답의 구성
상태 표시줄
2XX
- 응답 성공을 의미
201
- POST 메소드의 응답 성공을 의미
4XX
- 서버가 처리 불가능한 잘못된 요청을 의미
404
- 리소스 탐색 불가를 의미
메시지 본문
리소스 표현이 포함된 메시지를 의미하며, 일반적으로 XML이나 JSON의 형태로 반환됨
다음은 위에 대한 JSON 방식의 예시 데이터이다
1
2
3
4
5
{
"id":"testId1",
"pwd":"testPwd1",
"userName":"testUserName1"
}
헤더
- 응답에 대한 헤더 / 메타데이터 등이 해당되며, 인코딩이나 날짜 및 콘텐츠 유형 등의 정보를 포함한다
필요한 요소
Fetch
정의
- Javascript의 내장 라이브러리로, 비동기로 서버와의 통신을 담당한다.1
FormData
정의
- form필드와 동일한 방식으로 key/value의 데이터를 다루기 위한 객체
- XMLHttpRequest.send() 메소드를 이용하여, 데이터의 전송이 가능하다
- GET 전송의 경우, URLSearchParams 생성자에 직접 전달하는 방식으로 사용이 가능하다
메소드
- FormData.append(): 키가 존재할 경우 그 키에 새 값을 추가하고, 키가 존재하지 않는 경우에는 키와 값을 새로 추가함.
- FormData.delete(): FormData 객체에서 키/값 쌍을 삭제함
- FormData.entries(): 모든 키/값 쌍을 가져올 수 있는 iterator를 반환함
- FormData.get(): 키가 조건에 충족하는 첫번째 값을 반환함
- FormData.getAll(): 키가 조건에 충족하는 모든 값을 배열로 반환함
- FormData.has(): 특정 키가 있는지 여부를 boolean로 반환함
- FormData.keys(): 모든 키에 대한 iterator를 반환함
- FormData.set(): 기존 값에 새 값을 설정하거나, 새 키/값 쌍을 추가함
- FormData.values(): 모든 값에 대한 iterator를 반환함
사용 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const formData = new FormData(); //새 FormData 객체 생성
formData.append('id', 'tId1');
formData.append('id', 'tId2');
//id=tId1, id=tId2와 같은 방식으로 값을 저장한다
formData.get("id");
//첫번째 값인 tId1만을 반환한다
//전송 예시 코드
fetch('/url',{
method: "POST",
body: formData
});
- new FormData()를 이용하여, 새로운 FormData를 생성한다
- append()/get() 메소드를 이용하여 값의 생성 / 반환 / 변경이 가능하다
- 위의 예시 코드와 같이 fetch나 response등을 이용하여, FormData 객체의 전송이 가능하다
더 자세한 내용은 이 링크를 참조 바란다
CORS
정의
Cross-Origin-Resource-Sharing의 약자로, 웹페이지에서 다른 사이트에 접속할 수 있게해주는 메커니즘을 의미한다.
자바스크립트에서는 다른 도메인에 대한 요청을 보안상의 이유로 제한하는데(동일 오리진 정책), 이를 해결하기 위해서는 CORS를 설정할 필요가 있다.
- CORS가 존재하지 않을 경우, 다른 애플리케이션에서 가짜 클라이언트 요청 전송과 같은 보안상의 이슈가 존재한다
CORS의 작동은 다음과 같다.
- 브라우저는 현재 경로의 프로토콜, 호스트, 포트의 정보가 포함된 오리진 헤더를 요청에 추가한다.
- 서버는 현재 오리진의 헤더를 확인 및, 요청된 데이터와 Access-Control-Allow-Origin 헤더로 응답함
- 브라우저는 엑세스 제어 요청 헤더를 확인 후, 반환된 데이터를 클라이언트 애플리케이션과 공유함
- 서버에서 크로스 오리진 엑세스가 허용되지 않는 경우, 오류 메시지를 반환함
동일 오리진 정책
- 브라우저에서는 클라이언트가 동일한 오리진의 리소스로만 요청을 허용한다.
- 클라이언트의 URL의 프로토콜, 포트, 호스트가 모두 클라이언트가 요청하는 서버와 일치하는 경우에만, 요청이 허용된다.
- 예시) 클라이언트 URL : http://127.0.0.1:3000
URL 성공 여부 종류 실패 이유 http://127.0.0.1:3000/login.html O 동일 오리진 http://127.0.0.1:4000/main.html X 다른 오리진 다른 포트 http://126.0.0.1:3000/main.html X 다른 오리진 다른 호스트 - 위의 예시와 같이, 동일한 호스트와 포트를 가진 http://127.0.0.1:3000/login.html에서는 클라이언트가 요구하는 서버가 동일하므로, 클라이언트의 요청에 대해 오류 없이 정상 수행된다.
- 하지만, http://127.0.0.1:4000/main.html은 호스트만 동일하지만, 포트가 다르며, http://126.0.0.1:3000/main.html는 클라이언트와 호스트가 다르므로, 클라이언트의 요청이 정상 수행되지않는다.
메소드
Access-Control-Allow-Origin
- 요청을 허용할 특정 오리진을 설정하는 것
- ⁎: 모든 오리진으로 부터 접속을 허용
사용방법
1
2
3
4
Access-Control-Allow-Origin: URL
//예시
header('Access-Control-Allow-Origin: http://127.0.0.1:3000');
Access-Control-Allow-Methods
- 서버에서 허용할 메소드의 목록을 설정하는 것
- GET, POST, PUT, DELETE등이 사용 가능하다2
사용방법
1
2
3
4
Access-Control-Request-Method: method
//예시
header("Access-Control-Allow-Methods: POST");
Access-Control-Allow-Headers
- 허용되는 헤더들의 목록을 설정하는 것
사용 방법
1
2
3
4
Access-Control-Request-Headers: HeaderType
//예시
header("Access-Control-Allow-Headers: Content-Type");
CORS 사전 요청
- CORS 상호작용에서 일부 HTTP 요청은 복잡하기 때문에 실제 요청을 보내기 전에 메소드와 헤더의 확인을 진행한다.
- 일반적인 상황에서는 자동으로 발생되지만, 단순 요청은 사전 실행 요청은 생략된다.
- 2-3개의 구성으로 요청을 보내며, Access-Control-Request-Method, Origin을 필수적으로 받으며 Access-Control-Request-Headers를 선택으로 요청을 보낸다
작동방식
- 예시) DELETE 방식으로 요청이 있을 경우
- DELETE요청을 하기전에, 사전요청을 통해 서버에서 DELETE를 허용하는지 여부를 확인함
- 서버가 DELETE를 허용하는 경우, Access-Control-Allow-Methods에 DELETE를 포함하여 사전 요청에 응답한다.
참고한 자료
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.