상세 컨텐츠

본문 제목

Fetch API 통한 Ajax 구현 #2

PROGRAMMING/Web

by koharin 2021. 2. 24. 22:16

본문

728x90
반응형

Fragment Identifier


<!DOCTYPE html>
<html>
  <body>
  	<a href="#three">three</a>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam minima voluptatum iure iusto, sequi aperiam, totam reiciendis cum consequatur molestias exercitationem ex nulla? Reiciendis velit odit minus dolore, nihil consequuntur qui pariatur nesciunt cupiditate debitis porro, autem recusandae necessitatibus assumenda aut a molestias in aliquam eligendi, eius totam. Reprehenderit deleniti consequuntur incidunt culpa fuga maxime sed, reiciendis voluptate facere sapiente, pariatur! Suscipit possimus a at corrupti rerum. Pariatur praesentium, veniam vitae voluptates, quidem labore impedit ab quos soluta modi eveniet quia mollitia quod natus iste earum, dolorem minus! Ullam possimus commodi alias, et reiciendis provident quidem nesciunt atque repellendus cum?
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vero sint hic, omnis in at excepturi, ipsum perspiciatis distinctio, optio vitae veniam consectetur praesentium est! Minus repudiandae inventore blanditiis ullam sit culpa dicta soluta modi, totam ab consequatur laudantium temporibus aut perspiciatis aspernatur quos amet autem earum sequi! Voluptatem optio tenetur distinctio enim voluptatum sapiente praesentium, similique iste. Facilis cupiditate, vitae quisquam deleniti porro magnam neque autem perspiciatis itaque tenetur adipisci iste optio! Porro quidem mollitia ea, nemo, ab, quibusdam nihil sint quisquam rerum perspiciatis fugit, et consectetur odio rem eius obcaecati? Numquam vitae molestiae, alias aut, porro ab maxime fugiat.
    </p>
    <p id="three">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Earum soluta saepe, necessitatibus asperiores incidunt quis quibusdam aspernatur voluptatibus, distinctio nostrum nobis commodi sequi iusto vitae dicta! Magnam maiores deleniti iste sequi eveniet laudantium amet, sed adipisci? Nisi voluptates labore atque nihil quia, at tempora eius iure commodi dolore officia vitae ducimus excepturi. Asperiores maxime, atque cum ad deleniti illo sed ab nostrum dolor culpa mollitia molestiae vitae veritatis aut quibusdam accusamus aperiam, voluptatem nemo, cumque! Porro expedita, harum, nisi rerum nesciunt nobis impedit cumque ut ab quasi cupiditate beatae dolorem enim veniam accusantium autem odit reiciendis! Fugit soluta, vero optio.
    </p>
  </body>
</html>

p 태그에 id로 three라는 식별자를 주면, http://localhost/Ajax/hash..html#three로 줄 경우 페이지가 리로드되지 않고 3번째 문단으로 이동하게 된다. three라는 링크를 눌러도 세 번째 문단으로 이동하게 된다.

http://localhost/Ajax/hash.html 웹페이지 내의 fragment를 identifier를 통해 접근할 수 있다. 이때 three와 같은 fragment를 식별하는 id를 fragment identifier라고 한다.

 

location.hash는 http://localhost:8000/Ajax/hash#three에서 #three 값을 가지는 것을 확인할 수 있다.

 

<!DOCTYPE html>
<html>
  <body>
    <a href="#three">three</a>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam minima voluptatum iure iusto, sequi aperiam, totam reiciendis cum consequatur molestias exercitationem ex nulla? Reiciendis velit odit minus dolore, nihil consequuntur qui pariatur nesciunt cupiditate debitis porro, autem recusandae necessitatibus assumenda aut a molestias in aliquam eligendi, eius totam. Reprehenderit deleniti consequuntur incidunt culpa fuga maxime sed, reiciendis voluptate facere sapiente, pariatur! Suscipit possimus a at corrupti rerum. Pariatur praesentium, veniam vitae voluptates, quidem labore impedit ab quos soluta modi eveniet quia mollitia quod natus iste earum, dolorem minus! Ullam possimus commodi alias, et reiciendis provident quidem nesciunt atque repellendus cum?
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vero sint hic, omnis in at excepturi, ipsum perspiciatis distinctio, optio vitae veniam consectetur praesentium est! Minus repudiandae inventore blanditiis ullam sit culpa dicta soluta modi, totam ab consequatur laudantium temporibus aut perspiciatis aspernatur quos amet autem earum sequi! Voluptatem optio tenetur distinctio enim voluptatum sapiente praesentium, similique iste. Facilis cupiditate, vitae quisquam deleniti porro magnam neque autem perspiciatis itaque tenetur adipisci iste optio! Porro quidem mollitia ea, nemo, ab, quibusdam nihil sint quisquam rerum perspiciatis fugit, et consectetur odio rem eius obcaecati? Numquam vitae molestiae, alias aut, porro ab maxime fugiat.
    </p>
    <p id="three">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Earum soluta saepe, necessitatibus asperiores incidunt quis quibusdam aspernatur voluptatibus, distinctio nostrum nobis commodi sequi iusto vitae dicta! Magnam maiores deleniti iste sequi eveniet laudantium amet, sed adipisci? Nisi voluptates labore atque nihil quia, at tempora eius iure commodi dolore officia vitae ducimus excepturi. Asperiores maxime, atque cum ad deleniti illo sed ab nostrum dolor culpa mollitia molestiae vitae veritatis aut quibusdam accusamus aperiam, voluptatem nemo, cumque! Porro expedita, harum, nisi rerum nesciunt nobis impedit cumque ut ab quasi cupiditate beatae dolorem enim veniam accusantium autem odit reiciendis! Fugit soluta, vero optio.
    </p>
    <script>
      if(location.hash){
        console.log(location.hash.substr(1)); // #three이면 three만 
      }
    </script>
  </body>
</html>

 

#은 hash로 북바크 기능을 나타내고, 일반적인 경우에는 #!(Hash Bang)을 사용한다.

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 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>
  <article>
  </article>
  <script>
    function fetchPage(name){
      fetch(name).then(function(response){
        response.text().then(function(text){
          document.querySelector('article').innerHTML = text;
        })
      });
    }
    if(location.hash){ // if hash exists
      fetchPage(location.hash.substr(2));
    }else{
      fetchPage('welcome');
    }
  </script>
</body>
</html>

location.hash로 hash가 있는 경우, "#!html"에서 0~1번째 제외 2번째부터 가져오면 되므로 substr(2)를 줘서 fetchPage에 html을 인자로 준다. 그럼 해당 html 페이지를 로드해준다.

welcome

<h2>welcome</h2>
Hello, Ajax

location.hash가 없는 경우에는, welcome 페이지를 로드해준다.

링크를 누르지 않고 바로 http://localhost/Ajax/index.html#!css 링크로 가도 아래와 같이 css가 로드된 페이지를 확인할 수 있다.

 

 

Ajax의 단점은 검색엔진 최적화가 되지 않는다는 것인데, 내용은 백엔드에서 가져와서 내용이 없기 때문이다.

따라서 Ajax의 단점을 보완한 pjax라는 것을 사용할 수도 있다.

 

 

글 목록 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="#!welcome">WEB</a></h1>
  <input id="night_day" type="button" value="night" onclick="
    nightDayHandler(this);
  ">
  <ol id="nav">
  
  </ol>
  <article>
  </article>
  <script>
    function fetchPage(name){
      fetch(name).then(function(response){
        response.text().then(function(text){
          document.querySelector('article').innerHTML = text;
        })
      });
    }
    if(location.hash){ // if hash exists
      fetchPage(location.hash.substr(2));
    }else{
      fetchPage('welcome');
    }
    fetch('list').then(function(response){
      response.text().then(function(text){
        document.querySelector('#nav').innerHTML = text;
      })
    });
  </script>
</body>
</html>
//list
<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>

글 목록을 따로 list라는 파일에 저장하고, 글 목록이 들어가는 <ol> 태그에 id로 nav를 주면, fetch를 이용해서 list 파일에서 데이터를 읽어와서 id가 nav인 요소에 innerHTML로 HTML string을 추가할 수 있다.

 

 

list 파일에서 중복 제거하기


html,css,javascript

list 파일을 위와 같이 변경하고, 콤마를 구분자로 각 문자열을 원소로 가지는 배열을 만들면, 배열에서 꺼내서 text를 <li>태그로 목록을 각각 반복문으로 만들어주고 innerHTML로 text를 넣어준다.

fetch('list').then(function(response){
      response.text().then(function(text){
        var items = text.split(',');
        console.log(items);
        document.querySelector('#nav').innerHTML = text;
      })
});

items는 각 파일 이름을 원소로 갖고 있는다.

 

<!doctype html>
<html>
<head>
  <title>WEB1 - Welcome</title>
  <meta charset="utf-8">
</head>
<body>
  <h1><a href="#!welcome">WEB</a></h1>
  <input id="night_day" type="button" value="night" onclick="
    nightDayHandler(this);
  ">
  <ol id="nav">
  
  </ol>
  <article>
  </article>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="colors.js"></script>
  <script>
    function fetchPage(name){
      fetch(name).then(function(response){
        response.text().then(function(text){
          document.querySelector('article').innerHTML = text;
        })
      });
    }
    if(location.hash){ // if hash exists
      fetchPage(location.hash.substr(2));
    }else{
      fetchPage('welcome');
    }
    fetch('list').then(function(response){
      response.text().then(function(text){
        var items = text.split(',');
        var newContent = '';
        for(var i=0; i<items.length; i++){
          items[i] = items[i].trim(); // remove whitespace 
          newContent += '<li><a href="#!' + items[i] + '" onclick="fetchPage(\''+ items[i] + '\')">' + items[i] + '</a></li>';
        }
        document.querySelector('#nav').innerHTML = newContent;
      })
    });
  </script>
</body>
</html>

기존의 <li> 태그 요소들에서 html과 같은 파일 이름을 모두 반복문을 돌면서 items[i]로 바꿔주면 반복 횟수만큼 목록이 생긴다.

list에서 공백이 존재할 경우, 제대로 구해지지 않는 것을 방지하기 위해 items[i].trim()으로 whitespace를 제거해준다.

fetchPage() 함수에서 작은따옴표를 사용해야 하는데, 문자열을 처리하는 것과 구분하기 위해 \'으로 사용한다.

동일한 기능이 제대로 구현된 것을 확인할 수 있다.

만약, 글 목록을 추가하고 싶으면, 해당 파일 생성 후 list에 파일에 대한 이름을 적어주면 된다.

 

Ajax는 XMLHttpRequest라는 API로도 구현이 가능하지만, fetch API가 더 강력하고 유연한 조작이 가능한 구현 방법이라고 한다. 

 

 

Reference


 

728x90
반응형

관련글 더보기