세번째 코스(1) - Ajax 사용하기 fetch API

Edwin·2023년 2월 2일
0
post-thumbnail
  • 본내용은 생활코딩 강의를 요약정리한 것입니다.
  • 악마와 함께란? 매력적인 마성을 지니신 생활코딩 코치님께 돌리는 구독자의 애정표현
    생활코딩 WEB3, Ajax

악마와 함께 코딩을 Javascript 세번째 코스

javascript의 도입으로 웹은 동적으로 빠르게 변화되었다. 특히 대부분의 검색엔진들은 알파벳만 입력해도 추천검색어를 함께 보여주는 것을 볼 수 있다. 어떻게 이러한 일이 가능해졌을까? 사용자는 모르지만, 웹이 Ajax를 통해서 서버와 통신을 주고받으며 리로딩 없이 작동되었기 때문이다. 이러한 Ajax은 1999년 마이크로스프트사에 의해 처음 등장하였다. 처음등장했을 때 Ajax은 무명의 기술이었다. 하지만 5년 뒤인 2004년 구글이 gmail을 서비스하며 리로드 없이 메일함에 입력된 정보를 보여주며 Ajax을 활용하였고, 구글의 행보를 인하여 그동안 고정관념에 박혀있었던 Web 사용자들은 충격을 받게 되었다. 구글이 활용한 무명의 이 기술은 비로서 이름을 가지게 되었는데 바로 "Asychronous Javascript And Xml, Ajax"이다.

1) 수업의 목적

Ajax을 사용하기 이전에는 클라이언트-서버 간에 가져와야 하는 정보가 방대하였다면, 시간과 비용적 측변에서 클라이언트-서버 양측은 비례적으로 발생되는 가치를 지불해야 했었다. 그러나 Ajax을 활용하기 시작하면서, 필요한 부분의 정보만을 가져올 수 있게 되었고, 그 결과 이전에 비례적으로 발생되었던 지불을 축소시킬 수 있게 되었다. 실용적 측면에서 Ajax를 통해서 웹은 하나의 웹페이지에서 변동 가능한 부분을 손쉽게 제어함으로 가벼워질 수 있게 되었다. single-page application

2) 실습해보자(fetch API)

  • index.html 파일을 만들어서 진행하자.
<!doctype html>
<html>
<head>
  <title>WEB1 - Welcome</title>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="colors.js"></script>
</head>
<body>
  <h1><a href="index.html">WEB</a></h1>
  <input id="night_day" type="button" value="night" onclick="
    nightDayHandler(this);
  ">
  <ol>
    <li><a onclick="
      document.querySelector('article').innerHTML = '<h2>HTML</h2> HTML is...'">HTML</a></li>
    <li><a onclick="
      document.querySelector('article').innerHTML = '<h2>CSS</h2> CSS is...'">CSS</a></li>
    <li><a onclick="
      document.querySelector('article').innerHTML = '<h2>Javascrip</h2> Javascrip is...'">JavaScript</a></li>
  </ol>
  <article>
  </article>


</body>
</html>

최초의 왼쪽 페이지 목록에 있는 HTML을 클릭하자 오른쪽 페이지에 있는 것과 같이 <article> 태그에 이벤트가 발생된 것을 볼 수 있다. 이 부분을 Ajax을(fetch API) 활용하여 다뤄보고자 하는 것이 이번 실습의 핵심이다.

  <input type="button" value="fetch" 
  onclick="
  fetch('html').then(function(response) {
    response.text().then(function(text) {
      alert(text);
    })
  })
  ">

기본적으로 fetch API를 통한 Ajax의 기본 문법이 이와 같다. fetch API의 진행은 HTML 문서 내의 태그에서 1) 그 속성으로 onclick=""으로 이벤트를 발생시켜주고, 2) 그 내용의 값으로 fetch('해당 html 파일과 같은 폴더에서 불러올 파일명')을 요청하도록 설정한 후에, 응답으로서의 함수값으로 alert(text);부분을 실행해 주는 것이다. 3) 이때 alert(text);부분을 document.querySelector('article').innerHTML = text;와 같이 변경해 주면, 다른 방식으로도 작동이 가능한데, fetch('해당 html 파일과 같은 폴더에서 불러올 파일명')에서 불러온 인자를 매개변수로 받아, 입력해주는 방식으로 작동된다.

<!DOCTYPE html>
<html lang="ko">
<body>
  <article></article>
  
  <input type="button" value="fetch" onclick="
  fetch('html').then(function(response) {
    response.text().then(function(text) {
      document.querySelector('article').innerHTML = text;
    })
  })
  ">
</body>
</html>

위와 같이 기록했다면, type="button"을 클릭하면, fetch('html')에서 가져온 값이 <article>태그내에 기록될 것이다.

Asychronous(비동기적), 용어설명

<input type="button" value="fetch" onclick="
  function callbackme() {
    console.log('End');
  };

  fetch('html').then(callbackme);
      console.log(1);
      console.log(2);
      console.log(3);
      console.log(4);
  ">

이 코드에 따라서 웹페이지에는 button이 생성되었을 것이다. 이 버튼을 클릭하면, 해당 onclick 속성에 따라서 안에 기록된 javascript가 실행될 것인데, 본래의 개념에서는 fetch('html').then(callbackme);가 실행되어 console.log('End'); 경고창이 웹상에 뜬 다음에 console.log(1);가 실행될 것을 기대할 것이다. 그러나, fetch().then()에서 then()은 then()을 실행하면서 동시에 후속되는 작업을 이행하라는 명령이다. 그 결과 콘솔에서 다음과 같이 기록되는 것을 볼 수 있다.

fetch().then()가 실행 중에 있기에, 먼저 console.log(1);부터 console.log(4);가 실행되고, fetch().then()가 완료되면 그제서야 console.log('End');을 불러오는 것이다.

index.html에 fetch API 적용하기

<!doctype html>
<html>
<head>
  <title>WEB1 - Welcome</title>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="colors.js"></script>
  <link rel="stylesheet" href="/index.css">
</head>
<body>
  <h1><a href="index.html">WEB</a></h1>
  <input id="night_day" type="button" value="night" onclick="
    nightDayHandler(this);
  ">
  <ol>
    <li><a onclick="
      fetch('html').then(function(response) {
        response.text().then(function(text) {
          document.querySelector('article').innerHTML = text;
        })
      })
      ">HTML</a></li>
    <li><a onclick="
      fetch('css').then(function(response) {
        response.text().then(function(text) {
          document.querySelector('article').innerHTML = text;
        })
      })
      ">CSS</a></li>
    <li><a onclick="
      fetch('javascript').then(function(response) {
        response.text().then(function(text) {
          document.querySelector('article').innerHTML = text;
        })
      })
      ">JavaScript</a></li>
  </ol>
  <article>
  </article>


</body>
</html>

<a에 따라서 fetch API가 동작하며, 해당 index.html과 같은 폴더에 있는 html, css를 찾아서 각각의 이벤트가 발생되었을 때 document.querySelector('article').innerHTML를 통해 내용을 기록해줄 것이다.

중복되는 부분 리펙토링

3 개의 onclick을 보면 중복되는 부분이 있는 것을 봅니다. 이를 함수를 통해서 코드를 재활용하여, 정돈을 해보자. <script>태그를 통해서 함수 안에 중복되는 코드를 담고, 가변적인 요소는 인자로 받아서, 매개변수로 값을 전달하도록 하면 된다.

  <ol>
    <li><a onclick="fetchPage('html')">HTML</a></li>
    <li><a onclick="fetchPage('css')">CSS</a></li>
    <li><a onclick="fetchPage('javascript')">JavaScript</a></li>
  </ol>
  <script>
    function fetchPage(item) {
      fetch(item).then(function(response) {
        response.text().then(function(text) {
          document.querySelector('article').innerHTML = text;
        })
      })
    }
  </script>

3) Fetch에 따라 가변적인 url 설정(hashBang)

hash bang을 이용하면, url에 각각의 설정에 따라서 가변적인 효과를 줄 수 있다. 예를들어 초기값으로 /#!home 을 설정하는 것이다. single-page application이지만, html을 클릭해서 <article>태그를 불러올 때 url에 /#!html가 같이 기록해 주는 것이다.

이때 중요한 것이 식별자(id)값이다. <a href="#id">를 입력하면 해당 id가 있는 곳으로 이동하는 것이 가능했었다. 이를 활용하여 작업을 진행할 것이다.

먼저 <script> 태그에 조건문을 추가해 준다.

<script>
  function fetchPage(item) {
      fetch(item).then(function(response) {
        response.text().then(function(text) {
          document.querySelector('article').innerHTML = text;
        })
      })
    }

  if(location.hash) {
      fetchPage(location.hash.slice(2))
    } else {
      fetchPage('home')
    }
</script>

그리고 해당 조건문과, 함수가 작동할 HTML 부분에 href="#"을 추가해준다. 이때, hash를 알리고자 관용적으로 href="#!" 느낌표를 추가하여 기록해 준다.

 <ol>
    <li><a href="#!html" onclick="fetchPage('html')">HTML</a></li>
    <li><a href="#!css" onclick="fetchPage('css')">CSS</a></li>
    <li><a href="#!javascript" onclick="fetchPage('javascript')">JavaScript</a></li>
</ol>

작동원리는 다음과 같다.

  • 첫째, 버튼 HTML이 클릭되면, href="#!html"이 실행될 것이다.
  • 둘째, href="#!html"가 실행되면 조건문이 발생된다. location.hash웹페이지가 hash되었기 때문이다. 이때, 가져온 location.hash의 값에 해당되는 "#!html"에서 부분적으로 사용할 text만 추출하기 위해 slice(2) 또는 substring(2)를 조건문의 내용에서 다뤄주다. 조건이 충족되면, 해당값으로 fetchPage()가 실행될 것이다.
  • 셋째, fetchPage()은 "#!html"에서 가져온 text부분으로 fetch API를 실행하게 될 것이다.
  • 넷째, 이렇게 실행된 웹페이지는 single-page application이지만, 조건에 따라 별개의 url을 가지게 된다.
  • 다섯째, else 구분은 그렇지 않은 초기값으로 fetchPage('home') 둔다는 것으로 설정을 마친다.

이렇게 함으로 하나의 웹페이지는 각 요소에 따른 가변적인 url을 가지게 된다.다음은 위의 코드의 풀버전을 기록해 놓겠다.

<!doctype html>
<html>
<head>
  <title>WEB1 - Welcome</title>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="colors.js"></script>
  <link rel="stylesheet" href="/index.css">
</head>
<body>
  <h1><a href="#!home" onclick="fetchPage('home')">WEB</a></h1>
  <input id="night_day" type="button" value="night" onclick="
    nightDayHandler(this);
  ">
  <ol>
    <li><a href="#!html" onclick="fetchPage('html')">HTML</a></li>
    <li><a href="#!css" onclick="fetchPage('css')">CSS</a></li>
    <li><a href="#!javascript" onclick="fetchPage('javascript')">JavaScript</a></li>
  </ol>
  <script>
    function fetchPage(item) {
      fetch(item).then(function(response) {
        response.text().then(function(text) {
          document.querySelector('article').innerHTML = text;
        })
      })
    }

    if(location.hash) {
      fetchPage(location.hash.substring(2))
    } else {
      fetchPage('home')
    }
  </script>

  <article>
  </article>


</body>
</html>
  • link rel="stylesheet" href="/index.css"
    부분으로 필자는 link를 통해서 cursor로 pointer를 설정해주었다.
  • 또한 index.html과 같은 위치에, home/html/css/javascript 파일이 존재해야 해당 문서는 실행될 것이다. 즉 불러와서 <article>태그에 기록해줄 내용을 담은 문서가 함께 폴더에 있어야 한다는 것이다.

Author. EDWIN
date. 23/02/02

profile
신학전공자의 개발자 도전기!!

0개의 댓글