ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React.js(3)_Ajax
    SPA/React.js 2022. 9. 28. 12:00

    해당 게시글은 2022.04.28에 깃허브로 작성되었습니다.

     


     

    1. Ajax란?

    Asynchronous JavaScript and XML의 약자로,

    빠르게 동작하는 동적인 웹 페이지를 만들기 위한 개발 기법의 하나이다.

     

    Ajax는 웹 페이지 전체를 리로드하지 않아도 웹 페이지의 일부분만을(DOM) 갱신할 수 있다.

    즉, Ajax를 이용하면 백그라운드 영역에서 서버와 통신하여 그 결과를 웹 페이지의 일부분에 표시할 수 있다.

     

    이 때 서버는 아래와 같은 다양한 형태의 데이터를 주고받을 수 있다.

    JSON
    XML
    HTML
    텍스트 파일

     

    (1) Ajax의 장점

    Ajax를 이용하면 다음과 같은 장점이 있다.

    1. 웹 페이지 전체를 리로드하지 않고도 웹 페이지의 일부분만을 갱신할 수 있다.
    2. 웹 페이지가 로드된 후에 서버로 데이터 요청을 보낼 수 있다.
    3. 웹 페이지가 로드된 후에 서버로부터 데이터를 받을 수 있다.
    4. 백그라운드 영역에서 서버로 데이터를 보낼 수 있다.

     

    (2) Ajax의 한계

    1. Ajax는 클라이언트가 서버에 데이터를 요청하는 클라이언트 풀링 방식을 사용하므로, 서버 푸시 방식의 실시간 서비스는 만들 수 없다.

    [여기서 클라이언트 풀링 방식이란?]
    사용자가 직접 원하는 정보를 서버에게 요청하여 얻는 방식을 의미한다.

    이에 반해 서버 푸시(server push) 방식이란 사용자가 요청하지 않아도 서버가 알아서 자동으로 특정 정보를 제공하는 것을 의미한다.
    (요즘 스마트폰에서 각종 앱이 보내는 푸시 알림이 서버 푸시 방식의 대표적인 예이다.)

     

    2. Ajax로는 바이너리 데이터를 보내거나 받을 수 없다.

    [여기서 바이너리 데이터란?]
     컴퓨터 파일로 컴퓨터 저장과 처리 목적을 위해 이진 형식으로 인코딩된 데이터이다.

     

    3. Ajax 스크립트가 포함된 서버가 아닌 다른 서버로는 Ajax 요청을 보낼 수 없다.

     

    4. 클라이언트의 PC로 Ajax 요청을 보낼 수 없다.

     

    (3) Ajax 구성 요소

    - 웹페이지의 표현을 위한 HTML과 CSS

    - 데이터에 접근하거나 화면 구성을 동적으로 조작하기 위해 사용되는 DOM 모델

    - 데이터의 교환을 위한 JSON이나 XML

    - 웹 서버와의 비동기식 통신을 위한 XMLHttpRequest 객체

    - 위에서 언급한 모든 기술을 결합하여 사용자의 작업 흐름을 제어하는 데 사용되는 Javascript

     

    (4) Ajax 동작 원리

    Ajax를 이용한 웹 응용 프로그램은 Javascript 코드를 통해 웹 서버와 통신을 하게 된다.

    따라서 사용자의 동작에는 영향을 주지 않으면서도 백그라운드에서 지속해서 서버와 통신할 수 있다.

    위 그림의 동작원리는 아래와 같은 순서로 진행된다.

    1. 사용자에 의한 요청 이벤트가 발생한다.

    2. 요청 이벤트가 발생하면 이벤트 핸들러에 의해 Javascript가 호출된다.

    3. Javascript는 XMLHttpRequest 객체를 사용하여 서버로 요청을 보낸다.

    이 때 웹 브라우저는 요청을 보내고 나서 서버의 응답을 기다릴 필요없이 다른 작업을 처리할 수 있다.

    4. 서버는 전달받은 XMLHttpRequest 객체를 가지고 Ajax 요청을 처리한다.

    5 - 6. 서버는 처리한 결과를 HTML, XML 또는 JSON 형태의 데이터로 웹 브라우저에 전달한다.

    7. 서버로부터 전달받은 데이터를 가지고 웹 페이지의 일부분만을 갱신하는 Javascript를 호출한다.

    8. 결과적으로 웹 페이지의 일부분만이 다시 로딩되어 표시된다.

     

    (6) XMLHttpRequest 객체

    Ajax의 가장 핵심적인 구성 요소는 XMLHttpRequest 객체이며

    Ajax에서 XMLHttpRequest 객체는 웹 브라우저가 서버와 데이터를 교환할 때 사용된다.

    var httpRequest = new XMLHttpRequest();

     


     

    2. Fetch API

    (1) XMLHttpRequest 방식

    XMLHttpRequest 객체를 이용한 정통적인 초창기 비동기 서버 요청 방식이다.

    성능에는 문제가 없지만 코드가 복잡하고 가독성이 좋지 않다는 단점이 있다.

    // XMLHttpRequest 방식
    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function () {
    if (httpRequest.readyState == XMLHttpRequest.DONE && httpRequest.status == 200) {
    document.getElementById("text").innerHTML = httpRequest.responseText;
    }
    }
    httpRequest.open("GET", "ajax_intro_data.txt", true);
    httpRequest.send();

     

    (2) Fetch API 방식

    Fetch API는 기본적으로 XMLHttpRequest보다 더 강력하고 유연하다.

     

    이벤트 기반인 XMLHttpRequest과는 달리 Fetch API는 Promise 기반으로 구성되어 있어 비동기 처리 프로그래밍 방식에 잘 맞는 형태이다.

    그래서 then이나 catch와 같은 체이닝으로 작성할 수 있다는 장점이 있다.

    // Fetch API 방식
    fetch('ajax_intro_data.txt')
    .then( response => response.text() )
    .then( text => { document.getElementById("#t").innerHTML = text; } )
    /* 'fetch('서버주소')' 는 웹 브라우저에게 '이 서버주소로 요청해줘' 라는 의미이고,
    뒤에 .then이 붙으면 '요청 끝나고나서 이 할 일을 해줘!' 라는 것이다. */
    [여기서 Promise 기반이란?]
     Promise는 Javascript 비동기 처리에 사용되는 객체이다.
     비동기 처리란 특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 Javascript의 특성을 의미한다.

     

    또한 Fetch API는 JS 기본 라이브러리이기 때문에 Jquery와 같이 CDN과 같은 다른 작업을 하지 않아도 바로 사용할 수 있디.

     

    (2-1) Fetch 문법&사용법

    fetch("https://jsonplaceholder.typicode.com/posts", option)
    .then(res => res.text())
    .then(text => console.log(text));

    1. Fetch에는 기본적으로 첫번째 인자에 요청할 URL(가져오려고 하는 데이터의 주소) 이 들어간다.

    2. 기본적으로 http 메소드 중 GET으로 동작한다.

    3. Fetch를 통해 Ajax 호출 시 해당 주소에 요청을 보낸 다음, 응답 객체(Promise object Response)를 받는다.

    4. 그러면 첫번째 then에서 그 응답을 받게 되고, res.text() 메소드로 파싱한 text값을 return한다.

    5. 그 다음 then에서 return받은 text값을 받고 원하는 처리를 할 수 있게 된다.

     

    개발자 도구의 네트워크 탭에 가보면 Fetch를 통해 얻어온 데이터를 볼 수 있다.

     

    (2-2) response 프로퍼티와 메소드

    Fetch를 통해 요청을 하고 서버로부터 값을 응답받으면 .then을 통해 함수의 인자에 담기게 되는데 이 값은 Response 객체로서 여러가지 정보를 담고 있다.

    필요한 변수값이나 메소드를 뽑아내서 값을 얻으면 된다.

    - response.status
     HTTP 상태 코드

    - response.ok
     HTTP 상태 코드가 200과 299 사이일 경우 true

    - response.body
     내용

    - response.text()
     응답을 읽고 텍스트를 반환한다.

    - response.json()
     응답을 JSON 형태로 파싱한다. = 데이터를 Javascript 객체로 변환한다.

    - response.formData()
     응답을 FormData 객체 형태로 반환한다.

    - response.blob()
     응답을 Blob(타입이 있는 바이너리 데이터) 형태로 반환한다.

    - response.arrayBuffer()
     응답을 ArrayBuffer(바이너리 데이터를 로우 레벨 형식으로 표현한 것) 형태로 반환한다.

     

    응답 자료 형태 반환 메소드는 한번만 사용할 수 있다.

    만일 response.text()를 사용해 응답을 얻었다면 본문의 콘텐츠는 모두 처리된 상태이기 때문에

    뒤에 또 response.json()을 써도 동작하지 않게 된다.

     


     

    3. HTTP 요청 방식

    HTTP 요청에는 GET, POST 뿐만 아니라 PUT, DELETE같은 여러가지 방식이 존재한다.

     

    [HTTP Method 종류]

    METHOD 역할
    POST POST를 통해 해당 URI를 요청하면 리소스를 생성
    GET GET을 통해 해당 리소스를 조회
    PUT PUT을 통해 해당 리소스를 수정
    DELETE DELETE를 통해 해당 리소스를 삭제

     

    [URL과 URI의 차이는?]
    - URL
     흔히 웹 주소라고도 하며 컴퓨터 네트워크 상에서 리소스가 어디 있는지 알려주기 위한 규약이고 URI의 서브셋이다.

    - URI
    특정 리소스를 식별하는 통합 자원 식별자(Uniform Resource Identifier)를 의미한다.
    웹 기술에서 사용하는 논리적 또는 물리적 리소스를 식별하는 고유한 문자열 시퀀스다.

    둘의 가장 큰 차이점은 URI는 식별하고 URL은 위치를 가리킨다는 점이다.

     

     

    (1) GET Method

    GET: 존재하는 자원을 요청

    단순히 원격 API에 있는 데이터를 가져올 때 사용.

     

    Fetch 함수는 기본으로 GET 방식으로 작동하고 option 인자가 필요 없다.

    응답(response) 객체는 json() 메소드를 제공하고 이 메소드를 호출하면 응답(response) 객체로부터 JSON 형태의 데이터를 Javascript 객체로 변환하여 얻을 수 있다.

    // GET METHOD
    fetch("https://jsonplaceholder.typicode.com/posts/1")
    .then((response) => response.json())
    .then((data) => console.log(data))

     

    (2) POST Method

    POST: 새로운 자원 생성 요청

    폼 등을 사용해서 데이터를 만들어 낼 때 보내는 데이터의 양이 많거나, 비밀번호 등 개인정보를 보낼 때 사용

     

    새로운 POST 생성을 위해 method option을 POST로 지정해주고 headers option으로 JSON 포맷을 사용한다고 알려줘야 한다.

    body option에는 요청 데이터를 JSON 포맷으로 넣어준다.

    // POST METHOD
    fetch("https://jsonplaceholder.typicode.com/posts", {
    method: "POST", // POST
    headers: { // 헤더 조작
    "Content-Type": "application/json",
    },
    body: JSON.stringify({ // 자바스크립트 객체를 json화 한다.
    title: "Test",
    body: "I am testing!",
    userId: 1,
    }),
    })
    .then((response) => response.json())
    .then((data) => console.log(data))

     

    (3) PUT Method

    PUT: 존재하는 자원 변경(수정) 요청

    API에서 관리하는 데이터의 수정을 위해 사용

     

    method option만 PUT으로 설정한다는 점 제외하고는 POST 방식과 비슷하다.

    아예 전체를 body의 데이터로 교체해버린다.

    // PUT METHOD
    fetch("https://jsonplaceholder.typicode.com/posts", {
    method: "PUT",
    headers: {
    "Content-Type": "application/json",
    },
    body: JSON.stringify({
    title: "Test" // 아예 title 엘리먼트로 전체 데이터를 바꿈. 마치 innerHTML같이.
    }),
    })
    .then((response) => response.json())
    .then((data) => console.log(data))

     

    (4) PATCH Method

    PATCH: 존재하는 자원 일부 변경 요청

     

    body의 데이터와 알맞는 일부만을 교체한다.

    // PATCH METHOD
    fetch("https://jsonplaceholder.typicode.com/posts/1", {
    method: "PATCH",
    headers: {
    "Content-Type": "application/json",
    },
    body: JSON.stringify({
    title: "Test" // title만 바꿈. 나머지 요소는 건들지 않음.
    }),
    })
    .then((response) => response.json())
    .then((data) => console.log(data))

     

    (5) DELETE Method

    DELETE: 존재하는 자원 삭제 요청

     

    보낼 데이터가 없기 때문에 headers, body option이 필요 없다.

    // DELETE METHOD
    fetch("https://jsonplaceholder.typicode.com/posts/1", {
    method: "DELETE",
    })
    .then((response) => response.json())
    .then((data) => console.log(data))

     

     

     

    4. async / await 문법

    앞서 말했듯 Fetch의 return값 response는 Promise 객체이다.

    이는 async / await 문법으로 가독성 높게 코딩할 수 있다.

    fetch("https://jsonplaceholder.typicode.com/posts", option)
    .then(res => res.text())
    .then(text => console.log(text));
    
    // =
    
    (async () => {
    let res = await fetch("https://jsonplaceholder.typicode.com/posts", option);
    let text = await res.text();
    console.log(text);
    })()

    function 키워드 앞에 async 붙여주고

    비동기로 처리되는 부분 앞에 await 붙여준다.

     

    async가 붙은 함수는 Promise를 반환하고 Promise가 아닌 것을 Promise로 감싸 반환한다.

    await 키워드를 만나면 Promise가 처리(settled)될 때까지 기다린다.

     


     

    5. 실습

    글로만 읽고 이해하는 건 어려우니 지금껏 배운 걸 실습을 통해 익혀보자.

    우선 Ajax 실습을 진행할 폴더 생성 후 코드 에디터에서 열어준다.

     

    그 후 해당 경로로 들어가 fetch 폴더 속 내용을 복사하여 가져온다.

    루트 디렉토리에 css 파일과 fetch.html 파일 생성 후 아래와 같은 내용을 작성한다.

    // css
    <h2>CSS</h2>CSS is...
    <!-- fetch.html -->
      <article>
    
      </article>
      <input type="button" value="fetch" onclick="
        fetch('css').then(function(response){
          response.text().then(function(text){
            document.querySelector('article').innerHTML = text;
          })
        })
      ">

    그럼 아래와 같이 fetch 버튼을 눌렀을 때 css text 파일에 작성했던 내용이 HTML로 작성된다.

    과정을 하나하나 짚어보자.

    1. <button> 태그의 onclick 속성으로 내장 함수를 입력하여 버튼 클릭 시 익명 함수가 작동되도록 한다.

    2. fetch(css) 로 웹 브라우저에게 css 파일의 데이터를 서버에게 요청한다.

    3. 서버가 요청받은 데이터에 대한 응답이 끝나면 then 내부의 익명 함수를 실행시키는데

    4. 그 내용으로 response.text()로 인해 text를 반환하도록 한다.

    5. 반환된 text 값을 매개변수로 설정하여 css 파일의 내용을 article 속에 HTML문법으로 삽입시킴으로써 화면에 나타나게 한다.

     

    이렇듯 Fetch를 이용하면 리로드없이 브라우저 속 데이터의 내용만 변경함으로써 효율성을 높일 수 있다.

     

    추가적으로 서버 내에 데이터를 직접 관리하는 경우, 더 쉽게 Fetch로 반환시키는 방법이 있다.

      var items = text.split(',');

    위와 같이 split를 이용해 ,를 기준으로 원소를 나눠 배열로 만든 후 items 변수에 대입 후

    반복문을 이용해 items 배열의 내용을 태그에 삽입하는 방법도 있다.

     


     

    이렇게 Ajax에 대해 간단히 알아봤으니 이제 React와 연동하여 사용하는 방법에 대해 알아보자.

     

    'SPA > React.js' 카테고리의 다른 글

    [React] Firebase로 회원가입/로그인, 로그아웃  (0) 2022.10.26
    React.js(5)_React Redux  (0) 2022.09.28
    React.js(4)_React Ajax  (0) 2022.09.28
    React.js(2)_React Router  (0) 2022.09.28
    React.js(1)_React란?  (0) 2022.09.28
Designed by Tistory.