My Image

Django 포스팅

[JavaScript] fetch 함수로 데이터 불러오고 로딩 스피너 구현하기

Doyeon0430 | 2023년 08월 03일

Django 이미지

이번시간에는 XML 파일로 구성된 API를 자바스크립트로 가져오겠습니다.

이전 포스팅에서 파이썬의 BeautifulSoup를 사용했었는데 버퍼링이 생기면서 서버가 느려졌습니다.

그래서 서버에 접속할 때 불러오는 방식이 아닌 미리 접속한 후에 불러오는 최적화를 시켜줬습니다.

이러한 방식은 자바스크립트에 fetch 함수로 쉽게 표현할 수 있습니다.

 

  1. fetch 함수로 API 요청 - 문법

  2. fetch 함수로 API 요청 - templates

  3. fetch 함수로 API 요청 - JavaScript

 

 

1. fetch 함수로 API 요청 - 문법

fetch 함수는 자바스크립트 문법으로 비동기 방식으로 데이터를 가져오는 내장 함수입니다.

 

fetch 함수 문법

fetch(url, options)
    .then(response => Method(response))
    .then(data => process(data))
    .catch(error => Error(error))
    .finally(() => Finally());

response는 서버로부터 받은 응답을 처리합니다.

data는 응답받은 데이터를 처리합니다.

catch는 응답에 실패할 경우 오류를 처리합니다.

finally는 요청이 끝났을 때 메소드를 수행합니다.

https://www.kobis.or.kr에서 데이터를 가져올 때 response를 거칩니다.

응답에 성공하면 data / 응답에 실패하면 catch를 호출합니다.

마지막에 finally로 요청을 마무리합니다.

 

 

2. fetch 함수로 API 요청 - templates

이 게시물은 파이썬의 웹 프레임워크인 Django를 기반으로 제작되었습니다.

views.py에서 새로운 변수를 선언하고 html과 css로 테이블 형식을 만들었습니다.

 

1. views.py

from datetime import datetime, timedelta

today = datetime.today()
yesterday = today - timedelta(days=1)
target_date = yesterday.strftime("%Y%m%d")
key = env('API_KEY')
numbers = range(1, 11)

API url에 사용할 날짜와 key값을 넣어봤습니다.

또한 순위를 나타내기 위해 1부터 10까지 범위를 추가했습니다.

 

2. HTML 코드

<div class="tag_cap">대한민국 일별 박스오피스</div>
<div id="tableContainer">
    <div id="loadingSpinner"></div>
    <table class="container tag_table" id="movieTable">
        <caption style="text-align: left; caption-side: top; font-weight: bold;">[{{ yesterday_str }} 기준]</caption>
        <thead>
            <th>No</th>
            <th>영화 제목</th>
            <th>개봉일</th>
            <th>누적 관객수</th>
        </thead>
        <tbody id="movieTableBody">
            {% for i in numbers %}
            <tr>
                <td style="font-weight: bold; width: 5%;" id="rank{{ i }}">{{ i }}</td>
                <td style="text-align: left;" id="movieNm{{ i }}"></td>
                <td id="openDt{{ i }}"></td>
                <td id="audiAcc{{ i }}"></td>
            </tr>
            {% endfor %}
        </tbody>
        <caption>제공: 영화진흥위원회 API</caption>
    </table>
</div>

 

3. CSS 코드

/* 테이블 css */
.tag_cap {
    font-size: 1.5rem;
    font-weight: 900;
    text-align: center;
    margin-bottom: 0.5rem;
}

.tag_table thead th {
    padding: 0.5rem 0;
    border-top: 2px solid gray;
    border-bottom: 2px solid gray;
    text-align: center;
}

.tag_table tbody td {
    padding: 0.5rem 0;
    text-align: center;
    border-bottom: 1px solid rgb(196, 196, 196);
}

.tag_table caption {
    text-align: end;
}

#tableContainer {
    position: relative;
}

/* 로딩 스피너 */
#loadingSpinner {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border: 4px solid rgba(0, 0, 0, 0.8);
    border-top: 4px solid #ffffff;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    animation: spin 1s linear infinite;
    display: none;
}

다음으로 자바스크립트를 통해 데이터를 가져오겠습니다.

 

 

3. fetch 함수로 API 요청 - JavaScript

자바스크립트 fetch 함수로 XML 데이터들을 가져옵니다.

추가적으로 테이블에 값을 삽입하고 로딩 스피너를 작동시킬 겁니다.

 

1. JavaScript 코드 - 로딩 스피너

function showLoadingSpinner() {
    const loadingSpinner = document.getElementById('loadingSpinner');
    loadingSpinner.style.display = 'block';
}

function hideLoadingSpinner() {
    const loadingSpinner = document.getElementById('loadingSpinner');
    loadingSpinner.style.display = 'none';
}

 

2. JavaScript 코드 - 테이블

function renderMovieList(movieList) {
    for (const [index, movie] of movieList.entries()) {
        const rankCell = document.getElementById(`rank${index + 1}`);
        const movieNmCell = document.getElementById(`movieNm${index + 1}`);
        const openDtCell = document.getElementById(`openDt${index + 1}`);
        const audiAccCell = document.getElementById(`audiAcc${index + 1}`);

        rankCell.innerText = movie.rank;
        movieNmCell.innerText = movie.movieNm;
        openDtCell.innerText = movie.openDt;
        audiAccCell.innerText = `${movie.audiAcc}명`;
    }
}

위에서 for문을 사용해 테이블 id를 순차적으로 정렬했습니다.

그렇기에 자바스크립트에서도 값을 나열하고 테이블에 삽입해야합니다.

 

3. JavaScript 코드 - fetch 함수

const apiurl = '{{ key }}';
const day = '{{ target_date }}';

function fetchMovieData() {
    showLoadingSpinner(); // 로딩창 시작

    fetch(`https://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.xml?key=${apiurl}&targetDt=${day}`)
        .then(response => response.text())
        .then(data => {
            // XML 데이터를 파싱합니다.
            const parser = new DOMParser();
            const xmlDoc = parser.parseFromString(data, 'text/xml');
            const movies = xmlDoc.getElementsByTagName('dailyBoxOffice');

            // 영화 데이터를 담을 배열
            const movieList = [];

            // 영화 데이터를 반복하면서 배열에 데이터를 추가합니다.
            for (let i = 0; i < movies.length; i++) {
                const movie = movies[i];
                const rank = movie.querySelector('rank').textContent;
                const movieNm = movie.querySelector('movieNm').textContent;
                const openDt = movie.querySelector('openDt').textContent;
                const audiAcc = parseInt(movie.getElementsByTagName('audiAcc')[0].textContent).toLocaleString();

                movieList.push({ rank, movieNm, openDt, audiAcc });
            }
            renderMovieList(movieList);
            localStorage.setItem('box_office_data', JSON.stringify({ 'movie_list': movieList }));
        })
        .catch(error => {
            console.error('영화 데이터를 가져오는 중 에러 발생:', error);
        })
        .finally(() => {
            hideLoadingSpinner(); // 로딩창 끝
        });
}

window.onload = function () {
    fetchMovieData();
};

맨 처음 페이지가 onload되면 fetchMovieData가 실행됩니다.

함수가 실행되면서 로딩 스피너가 작동합니다.

그리고 fetch 함수를 통해 API 데이터들을 불러오고 값들은 renderMovieList로 보냅니다.

 

4. fetch 함수 결과화면

디장고 fetch 함수 결과화면

댓글 (0)

    댓글이 없습니다.

간편 댓글 작성

My Image My Image My Image My Image