대범하게

[React] 비동기 통신과 AJAX와 fetch 함수 한 번에 보기 본문

Development/React

[React] 비동기 통신과 AJAX와 fetch 함수 한 번에 보기

대범하게 2023. 1. 11. 11:16
반응형

0. Before enter to Fetch, What is AJAX?

HTML에서 화면을 이동하기 위한 방법이 어떤 것이 있을까?

<a href=""> 방식으로 주소를 줘서 이동하는 것을 생각할 수 있을 것이다.

그러나 이 방식은 화면 전체를 교체하는 것이기 때문에 이동할 때마다 화면이 깜빡거리게 될 뿐더러 페이지의 용량이 크다면 전환까지의 시간이 오래 걸린다. 

심지어 자바스크립트는 싱글 스레드 방식이기에 하나의 스레드에서 모든 것을 돌려야 한다. 이를 보완하기 위해 비동기 통신이라는 개념이 등장했다. 여기서 잠시 비동기가 무엇인가 하면, 비동기란 자바스크립트에서 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 것을 의미한다.

비동기적 자바스크립트 동작을 하는 기술들을 통틀어 Ajax라고 부르는데, Ajax를 이용해서 데이터를 불러오는 동안 다음 코드를 진행하는 것이 가능해진다.

 

1. 태초부터 존재한 AJAX

AJAX(Asynchronous JavaScript And XML, 비동기적 JavaScript와 XML)는 서버에서 추가 정보를 비동기적으로 가져올 수 있게 해주는 포괄적인 기술을 나타내는 용어로 만들어진 지 오래되었다. 

 

브라우저가 가지고 있는 XMLHttpRequest 객체를 이용해서 전체 페이지를 새로고침 하지 않고 페이지의 일부만을 위한 데이터를 가져오는 기법이다.

기존에는 XMLHttpRequest API를 통해 통신을 주고 받았지만 엄청나게 번거로운 작업이었다. 

불편함을 개선하기 위해 JQuery를 통해 구현하기 시작하다가 이후 fetch API가 ES6 표준으로 등장하면서 fetch API를 통해 통신하는 것이 주요 방식으로 자리를 잡았다. 

 

이렇게 말해도 이론적으로 줄줄 아직 AJAX가 와닿지는 않는다. 비동기적 자바스크립트 동작을 하는 기술을 AJAX라고 부른다고 했을 때 비동기적, 즉 먼가 뒤에서 일어나는 일 같다. 뒤에서 일어나는 보통 몰래몰래 진행되고, 그렇게 몰래몰래 서버로 데이터를 요청한다고 생각하면 된다. 

 

2. AJAX는 서버로 몰래 데이터 요청하는 코드

AJAX가 서버로 몰래 데이터를 요청하는 코드라고 했을 때, 서버는 무엇인가?

간단하게 말하면 "서버 유저가 데이터를 요구하면 데이터를 보내주는 프로그램"이다.

ex) 네이터 웹툰 서버 => 유저: 웹툰 주세요

ex) 유튜브 서버 => 유저: 유튜브 주세요

 

But, 서버에게 요청할 때는 정해진 방법이 있다.

[방법] 원하는 데이터 URL이 뭔데? => 그 URL로 GET 요청을 해. => 그럼 줄게 

 

1. 원하는 데이터 URL이 뭔데 

- [서버 개발자가 만든 API] comic.naver.com 으로 요청하면 웹툰 준다.

 

2. 그 URL로 GET 요청을 해라 

[GET 요청을 하는 3가지 방법]

 1) 검색창에 URL을 넣어서 GET 요청

 2) 버튼으로 GET 요청 : 브라우저가 새로고침됨 

 3) AJAX로 GET 요청: 새로고침 없이 서버에게 GET 요청하는 쪼그만한 JS 코드

 

3. 그럼 준다. 

 

3. 자바스크립트로 AJAX 날리는 방법

GET 요청을 보내는 3가지 방법 중 AJAX로 요청하는 방법에 대해 더 알아보자.

 

1) 요즘 JS 방식 

  fetch("https://codingapple1.github.io/price.json")
    // 첫번째 then 괄호 안 => callback 함수
    .then((response) => {
      if (!response.ok) {
        throw new Error("400 아니면 500 에러남");
      }
      return response.json(); // 서버가 보낸 데이터
    })
    // 두번째 then => 수신한 데이터를 출력해보고 싶음
    .then((결과) => {
      console.log(결과);
    })
    // 에러 처리
    .catch(() => {
      console.log("에러남");
    });

 

2) 외부 라이브러리 방식 - axios

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

<script>
  axios
    .get("https://codingapple1.github.io/price.json")
    .then((result) => {
      console.log(result.data); // 서버에서 받아온 데이터
    })
    .catch(() => {
      console.log("에러남");
    });
</script>

3) fetch 

=> 불편함을 개선하기 위해 JQuery를 통해 구현하기 시작하다가 이후 fetch API가 ES6 표준으로 등장하면서 fetch API를 통해 통신하는 것이 주요 방식으로 자리를 잡았다. 

fetch에 대해 더 알아보자.

 

4. fetch 작동 방식

fetch란?

fetch()의 기본 문법은 다음과 같다.

let promise = fetch(url, [options])

- url: 접근하고자 하는 URL

- options: 선택 매개변수, method나 header 등을 지정할 수 있다.

fetch(url, options)
.then((response) => console.log("response:", response))
.catch((error) => console.log("error:", error));

 

fetch 함수는 API를 사용하여 백엔드 서버와 비동기 요청을 하는 방식 중 하나이다. (위에서 AJAX, axios 등 여러 종류가 있는 것을 확인하였다.) fetch API는 3개의 interface를 도입하고 있는데 Header, Request, Response이다.

 

4-1) Header

Headers 객체는 HTTP header와 대응되는 객체이다.

 

4-2) Request

Request는 HTTP 요청을 통해 자원을 가져오는 인터페이스이다.

Request는 URL, Header, Body가 필요하다.

 

4-3) Response

1. method

=> GET, POST, DELETE 등이 있다. GET 이외의 HTTP 메소드를 사용할 시 method 옵션을 명시해주어야한다. 

 

1) GET은 어떠한 정보를 가져올 때

: 메서드의 디폴트값이 GET이기 때문에 아무런 정보를 적지 않으면 GET으로 적용된다. 

 

2) POST는 어떠한 정보를 백으로 보낼 때

headers에는 부가적인 정보가, body에는 POST로 보내는 데이터가 들어간다.

3) DELETE는 단어 그래도 삭제할 때 사용한다. 

 

2. headers

: API 응답에 대한 헤더 정보를 담고 있다. (?)

 

3.  body

: 전달하고자 하는 응답 내용이다. 백과 통신할 때는 객체로 통신하기 때문에 객체 타입으로 작성해야 한다.

 

method, headers, body는 전달하고자 하는 정보이기 때문에 정보를 가져올 때, 즉 GET하는 경우에는 작성해줄 필요는 없다.

fetch("http://localhost:8000/login/", {
  method: "POST", // POST이기 때문에 어떠한 정보를 백으로 보낼 때
  header: { // API 응답에 대한 헤더정보 담고 있음
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    email: "dabom",
    password: "1234",
  }),
})
  .then((response) => response.json())
  .then((response) => {
    if (response.token) {
      localStorage.setItem("wtw-token", response.token);
    }
  });
// 아직 완벽하게는 이해 못한 로그인 기능 구현 코드
// From https://velog.io/@daybreak/React-Fetch%ED%95%A8%EC%88%98
class Login_GH extends React.Component{
    state ={
        loginEmail : "",
        loginPw : "",
        btnColor : true
    }

fetch("http://10.58.7.154:8000/accounts/signin", {
          method: "POST",
          headers: {
            'Content-type': 'application/json'
        },
          body: JSON.stringify({
            email: this.state.loginEmail,
            password: this.state.loginPw
          })
        })
        // .then(response => console.log("response"))
          .then(response => response.json())
          .then(response => {
        
            if (response.token) {
              localStorage.setItem("wtw-token", response.token);
              this.props.history.push("/main_gh");
            } else if (!response.token) {
              alert("올바른 회원이 아닙니다");
              this.props.history.push("/signup_gh");
            }
          });

+ alpha

fetch is not defined

node로 fetch를 사용한 스크립트를 실행하면 오류가 발생한다. 이유는 node에서 실행하려고 하기 때문에 문제가 발생한 것이다. fetch는 브라우저에 내장된 함수이기 때문에 html에 src로 연결하고 해당 웹페이지에서 확인을 하면 제대로 출력되는 것을 볼 수 있다. 

node로 fetch를 실행하는 방식은 라이브러리를 사용하면 가능하다고 한다.

 

then 함수

자바스크립트에서 함수는 동기함수, 비동기 함수로 나뉜다.

동기함수에서는 코드들이 위에서 아래로 순차적으로 코드가 실행되고 하나의 코드가 종료되지 않는다면 다음 코드로 넘어가지 않는다.

비동기함수에서는 코드가 종료되지 않더라도 자동적으로 다음 코드로 넘어간다.

fetch는 대표적인 비동기함수로, API로부터 받아온 정보를 사용할 필요가 있는 경우에 .then 함수를 써서 작동이 끝날 때까지 멈춰놓을 수 있다.

 

endpoint

fetch에 넣는 url 중 중복되는 부분을 변수에다 할당해서 중복을 줄이는 방법.

endpoint를 위한 변수를 만들어서 주소를 할당하는 방식으로 쓰인다. (아직 완벽하게 이해 안 됨)

 

fetch 컴포넌트 

then, catch 보다 async, await/ try, catch를 사용하는 것이 최신 문법

 

Reference

https://velog.io/@sham/Fetch%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

https://ko.javascript.info/fetch

https://www.youtube.com/watch?v=nKD1atl6cAw 

 

 

Comments