본문 바로가기
Data Science

Javascript AJAX 예제, 비동기 데이터 불러오기 (전기자동차 데이터 분석 예제)

by 한입만쥬 2023. 6. 21.

이번 예제에서는 자바스크립트 AJAX 예제를 통해 비동기 통신을 활용하기 위한 코드를 알아보겠습니다. 

 

미국 워싱턴 주의 전기차 등록 현황에 대한 데이터 셋 'eleclist.xml'을 다운로드해서 예제에 사용하였습니다! 

필요하시면 댓글로 말씀 주세요. (xml 파일 출처 : data.gov)

 

 

간단하게 비동기 통신에 대한 개념은 이전 포스트를 참고해 주세요 : 

 

Javascript: 비전공자도 쉽게 이해하는 AJAX 개념 정리

AJAX ajax : Asynchronous Javascript and Xml ajax를 사용하면 서버에 요청한 후, 페이지를 다시 로딩하지 않고 일부를 업데이트할 수 있습니다. 비동기 요청으로 새로고침(페이지 로딩)이 다시 되지 않았다

joy-home.tistory.com


그럼 오늘의 예제를 살펴보겠습니다! 

 

HTML body 부분의 코드는 간단하게 버튼과 테이블로 구성되어 있습니다. 테이블은 시작할 때는 비어 있기 때문에 실행창에서는 ajax라는 버튼만 보이게 됩니다. 

 

<body>
    <button onclick="ajaxTest();">ajax</button>
    <table border="1" id="tb">

    </table>
</body>

 

Javascript 

자바스크립트 기본적인 구조는 아래와 같습니다. xhr이라는 변수에 XMLHttpRequest() 라는 js 객체를 만들어주고 xhr.open과 xhr.send로 콜백을 해서 함수를 실행하는 구조입니다. 완성된 코드는 하단으로 내려 주세요!

function ajaxTest() {
    // js 객체인 XMLHttpRequest 만들기 
    var xhr = new XMLHttpRequest();

    // callback : 필요할때만 실행되는 함수 
    // readystate가 바뀔 때마다 실행됨 
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) { // 통신이 완료되었을 때 
            if (xhr.status == 200) { // 상태코드가 성공일 때
                // responseXML : xml 객체로 반환 (타입=document)
                var respXML = xhr.responseXML; // 데이터를 respXML에 document로 넣어주기

            } else {
                alert(error); // // 오타 났을 때 emplist에서 뭘 받아오지 못해서 에러 뜸
            }
        }
        xhr.open('GET', 'eleclist.xml') // xhr 열어서 GET 방식으로 url 열기
        xhr.send();
    }
}

주석 처리해 둔 내용대로, 통신이 완료되고 상태 코드 (status code)가 200으로 성공일 때, 어떤 데이터를 가져오는 구조입니다. 이제 이것에 살을 채워 넣어주면 됩니다. 

우선 xml 파일을 보면 vin, county, city, model 등 여러 종류의 데이터가 <row> </row> 태그로 감싸져서 반복되고 있는 것을 확인할 수 있습니다. (아래 스크린샷 참고!) 즉, 한 row 가 하나의 데이터 엔티티라는 것이라는 뜻입니다.

 

그럼 저희가 테이블로 출력하기 위해 해야할 일은 : 

  1. 저희의 xml 파일에서 각 row 데이터를 가져오고
  2. row 데이터의 자식요소들 (vin_1_10, county, city ... ) 안의 text를 각각 cell에 넣어주고
  3. 자식요소들의 text를 넣은 cell을 하나의 행으로 묶어주고
  4. 묶어준 행을 테이블에 추가해주면 됩니다!

(코딩할 때는 이렇게 내가 해야 할 것들을 단계별로 쪼개서 주석처리를 해놓거나 적어 놓고 코드를 작성하는 것이 비전공자들에게는 추천하는 방법입니다! 저도 실제로 그렇게 하면서 코드 구조화하는 것을 더 잘 익히고 있는 중이거든요!)

 

그래서 이것을 코드로 작성해보면 아래와 같이 완성됩니다. 

function ajaxTest() {
            // js 객체인 XMLHttpRequest 만들기 - 이게 페이지의 일부 업데이트를 가능하게 해줌 
            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function () {

                if (xhr.readyState == 4) { // 통신이 완료되었을 때 
                    if (xhr.status == 200) {
                        // responseXML : xml 객체로 반환 (타입=document)
                        var respXML = xhr.responseXML; // 데이터를 respXML에 document로 넣어주기

                        var table = document.getElementById('tb');

                        var rows = respXML.getElementsByTagName('row'); // ROW들을 노드 리스트 rows로 저장 
                        console.log(rows);

                        var tr = document.createElement('tr');
                        for (var i = 0; i < rows[0].children.length; i++) {
                            var th = document.createElement('th');
                            th.appendChild(document.createTextNode(rows[0].children[i].nodeName));
                            tr.appendChild(th);
                        }
                        table.appendChild(tr); // header row 화면에 추가

						// 1. tr 만들어서
                        for (var i = 0; i < rows.length; i++) {
                            var tr = document.createElement('tr');
                            
                            // 2. tr 안에 ROW 하나의 내부 값을 td로 저장 
                            for (var j = 0; j < rows[i].children.length; j++) {
                                var td = document.createElement('td');
                                td.appendChild(document.createTextNode(rows[i].children[j].textContent));
                                tr.append(td);
                            }
                            // 3. 테이블에 추가 
                            table.appendChild(tr);
                        }
                    } else {
                        alert('error');
                    }
                }
            }
            xhr.open('GET', 'eleclist.xml') // xhr 열어서 GET 방식으로 url 열어라 
            xhr.send(); // 호출해라 (이게 실행될 때 readystate가 하나씩 올라감)
        }

 

실행시켜 보면 아래와 같이 예쁘게 테이블로 데이터를 가져올 수 있습니다. 저는 이번 예제에서는 css를 추가하지 않았지만, 여기에 추가하면 원하는 데이터를 더 명확하게 구별할 수도 있겠죠 ;) 

ajax 데이터 가져오기 실행 결과

여기서 주목해야 할 것은, 이 데이터를 가져올 때 페이지를 새로고침(reload) 한 것이 아니라는 점입니다! Javascript AJAX 비동기 통신으로 실행했기 때문이죠. 그래서 브라우저의 개발자도구 console을 열어보면 ajax 버튼을 누른 후에 한 번 더 눌렀을 때 rows 출력이 두 번 된다는 것을 확인할 수 있습니다.

 

추가적으로 제가 알게된 점은 

  • .children 과 .childNodes의 차이점 : children은 태그 요소들만 가져오지만 child nodes는 text까지 모두 가져옵니다! 
  • .append() 와 .appendChild() 차이점 : 
    • append는 TextNode를 따로 생성하지 않고 '바로' 삽입 가능, 2개 이상의 객체 삽입 가능
    • appendChild는 createTextNode로 생성 후 삽입 필요. string을 바로 넣으려고 하면 에러 생김 
    • 공통점 : 둘 다 Node 객체를 Element의 마지막 자식으로 삽입
  •  
var parent = document.createElement('div');
var child = document.createElement('p');

parent.append(child);
console.log(parent);

// 결과: <div><p></p></div>

 


 

이번 예제는 제가 직접 실습 데이터를 찾아보고 작성하는 것이라서 더 뿌듯하네요 :-) 

이 연습용 데이터 파일은 미국 오픈소스 데이터베이스에서 다운로드한 것인데, 필요하신 분들은 댓글 남겨 주시면 공유드리겠습니다. 만약 다른 파일로 실습해 보고 싶으시다면 xhr.open() 부분에서 url만 바꿔주시면 될 것입니다!!