상세 컨텐츠

본문 제목

Fetch API 통한 Ajax 구현 #1

PROGRAMMING/Web

by koharin 2021. 2. 24. 18:19

본문

728x90
반응형

fetch API 사용법


fetch.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Fetch Test #1</title>
    </head>
    <body>
        <input type="button" value="fetch" onclick="
        fetch('css').then(function(response){
        	response.text().then(function(text){
        		alert(text);
        	})
        })
        ">
    </body>
</html>

css

<h2>CSS</h2>CSS is ....

 

웹서버 상에 css 파일이 존재하고, fetch.html에서 fetch('css') 할 경우, fetch.html 코드에서 버튼을 누르면 css 데이터를 다운받는다.

그리고 css 파일의 내용이 alert 창에 나온다.

html

<h2>HTML</h2>HTML is ....

그렇다면, 위의 html 파일의 내용을 경고창에 띄우고 싶으면, 다음과 같이 fetch.html 내용을 변경하면 된다.

fetch.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Fetch Test #1</title>
    </head>
    <body>
        <input type="button" value="fetch" onclick="
        fetch('html').then(function(response){
        	response.text().then(function(text){
        		alert(text);
        	})
        })
        ">
    </body>
</html>

버튼을 누르면 웹서버에 html 파일을 요청하게 되고, 응답이 끝나 모든 작업이 완료되면 alert(text);가 실행되어 경고창이 뜨는 것이고, text 변수 안에는 웹서버가 응답하여 보낸 데이터가 들어있다는 것을 알 수 있다.

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Fetch Test #1</title>
    </head>
    <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>

 

 html 웹페이지의 내용을 가져오고 싶으면, 서버로부터 html 데이터를 담은 text를 document.querySelector('article')을 통해 article 요소를 선택하고, innerHTML로 text를 주면 된다.

 

fetch 버튼을 누르면 위와 같은 결과를 얻을 수 있다.

 

 

fetch API 요청 & 응답


fetch('javascript') : client가 server에게 javascript라는 파일을 응답해달라고 요청하는 것

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Fetch Test #1</title>
    </head>
    <body>
    	<article>
    	</article>
        <input type="button" value="fetch" onclick="
        fetch('html');
        ">
    </body>
</html>

버튼을 누를 때마다 html파일에 접속해서 데이터를 가져오는 것을 확인할 수 있다.

fetch(): 첫번째 인자로 준 파일의 데이터를 서버에게 요청하는 파일

then: 서버가 언제 응답해줄지 모르기 때문에, 서버가 응답해줄 때까지 다른 일을 하고 있도록 하는 역할. 만약 fetchAPI가 작업이 끝나면 then 인자로 준 일을 하도록 한다.

function callbackme(){
	console.log('response end');
}
fetch('html').then(callbackme);

fetchAPI가 html 파일의 데이터를 가져오는 작업이 끝나면(응답이 끝나면), then의 인자로 준 callbackme 함수를 실행하도록 한다.

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Fetch Test #1</title>
    </head>
    <body>
    	<article>
    	</article>
        <input type="button" value="fetch" onclick="
          function callbackme(){
              console.log('response end');
          }
          fetch('html').then(callbackme);
        ">
    </body>
</html>

Network 탭에서 esc 키를 누르면, console 창도 함께 볼 수 있다.

html 파일 데이터를 가져온 후, callbackme 함수를 실행하여 console에서 response end를 확인할 수 있다.

 

fetchAPI에 html 파일 데이터를 가져오고, then을 통해 callbackme 함수를 실행해달라고 서버에 요청하면, 이후의 코드들이 실행된다. 웹브라우저에서 응답받는 것이 끝나면, callbackme 함수가 호출되어 reponse end가 로깅되는 것이다.

이 과정을 통해, fetchAPI는 Asynchronous 방식(비동기 방식)으로 동작하는 것을 알 수 있다.

동기 방식은 요청에 대한 응답이 끝날 때까지 console.log(1); console.log(2) 코드들이 실행되지 못한다.

하지만 비동기 방식으로 동작하기 때문에 요청에 대한 응답이 끝나지 않아도 다른 코드가 동시에, 병렬적으로 실행될 수 있다. 

 

 

fetch API Response 객체


익명 함수: 이름이 없는 함수. 특정 함수의 인자 등으로 특정 경우에만 호출되는 경우 이름이 필요없는 익명 함수를 사용한다.

callbackme = function(){
  console.log('response end');
}
fetch('html').then(callbackme);

위와 같이 나타내면, callbackme는 function(){ .. } 함수와 동일하다.

따라서 따로 정의하지 않고, then에 function(){...}을 인자로 주는 방법으로 사용하는 것도 동일한 결과를 가져온다.

fetch('html').then(function(){
  console.log('response end');
});

 

callback 함수를 fetchAPI가 실행시킬 때, function의 첫 번째 인자로 response 객체를 준다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Fetch Test #1</title>
    </head>
    <body>
    	<article>
    	</article>
        <input type="button" value="fetch" onclick="
          fetch('html').then(function(response){
              console.log(reponse);
          });
          console.log(1);
          console.log(2);
        ">
    </body>
</html>

함수의 인자로 준 Response 객체가 console에 로깅된 것을 확인할 수 있다.

Response 객체는 속성으로 status이 있는데, 이는 웹브라우저와 웹서버가 서로 통신할 때, 웹서버가 요청한 작업을 제대로 수행했을 경우 응답으로 status: 200을 보낸다. (정상 응답)

 

웹브라우저가 요청한 파일이 웹서버에 존재하지 않다면, 서버는 404 (Not Found)을 status 값으로 Response 객체에 보낸다.

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Fetch Test #1</title>
    </head>
    <body>
    	<article>
    	</article>
        <input type="button" value="fetch" onclick="
          fetch('javascript').then(function(response){
              if(response.status == '404'){
                  alert('Not Found');
              }
          });
          console.log(1);
          console.log(2);
        ">
    </body>
</html>

 

 

 

Ajax 적용 


<!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="
      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>

각 HTML, CSS, JavaScript를 누르면, 해당 html, css, javascript 파일에서 데이터를 가져오고, 이 내용을 article 요소 내부 HTML로 내용을 보여준다.

 

 

리팩토링 - 함수화


하지만, html, css, javascript로 인자로 주는 파일이름만 다른데, 똑같은 코드를 세 번이나 반복적으로 사용하는 것은 비교율적이다. 

따라서 중복인 것은 제거하고, 중복이 아닌 것은 남기는 작업이 필요하다.

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

이렇게 따로 중복되는 부분을 fetchPage라는 함수로 만들어주고, 바뀌는 fetch의 인자를 fetchPage의 함수의 매개변수인 name으로 주면, fetchPage('html'), fetchPage('css') 등 변하는 인자마다 다르게 적용해서 줄 수 있다.

<!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="fetchPage('html')">HTML</a></li>
    <li><a onclick="fetchPage('css')">CSS</a></li>
    <li><a onclick="fetchPage('javascript')">JavaScript</a></li>
  </ol>
  <article>
  </article>
  <script>
    function fetchPage(name){
      fetch(name).then(function(response){
        response.text().then(function(text){
          document.querySelector('article').innerHTML = text;
        })
      });
    }
  </script>
</body>
</html>

똑같은 작업을 하는 코드를 위와 같이 변경하면, 코드의 유지보수, 가독성이 좋아진다.

 

 

 

 

Reference


생활코딩:WEB3 Ajax>fetch API

생활코딩:WEB3 Ajax>Ajax의 적용

728x90
반응형

관련글 더보기