반응형

 

Ajax

 

: 비동기적으로 데이터를 주고 받는 방식으로 서버와 데이터를 교환하는 기술의 하나다.

전체 페이지를 리로드 하지 않고 웹 페이지의 일부를 업데이트 가능하게 한다.

 

 

- Ajax 동작 원리

 

Ajax 동작 원리

 

 

 

서버 Request

 

 

XMLHttpRequest객체를 이용하여 전체 페이지를 다시 로드 하지 않고 웹 페이지의 일부를 업데이트 할 수 있게 한다.

 

 

  • 속성
속성 설명
onreadystatechange readyState값이 변경될 때 호출할 함수 정의
readyState 0: 요청 준비             1: 서버 연결 완료
2: 요청 받음             3: 요청 처리 중
4: 요청 처리 완료 후 응답 준비
responseText 서버로부터 반환된 응답 정보 (문자열)
responseXML 서버로부터 반환된 응답 정보 (XML)
Status 요청에 대한 상태 코드
200: “ok” 403: “Forbidden” 404: “Not Found”
statusText 요청에 대한 상태 문자

 

 

 

  • 메소드
메소드 설명
Open(method, url, async, user, pw) 요청 설정
method : 요청 유형 (get/post)
url : 호출할 url
async : 비동기 호출 여부 (true/false)
new XMLHttpRequest() XMLHttpRequest 객체 생성
abort() 현재 요청 취소
getAllResponseHeaders() header 정보 반환
getResponseHeader(key) header 정보 중 특정 값 반환
send() 서버로 요청 전송 (get방식)
send(string) 서버로 요청 전송 (post방식)
setRequestHeader() 요청 header에 정보 설정

 

 

 

서버 Response

 

 

  • 속성
속성 설명
responseText 서버로부터 반환된 응답 정보 (문자열)
responseXML 서버로부터 반환된 응답 정보 (XML)

 

 

 

  • 메소드
메소드 설명
getResponseHeader(key) header 정보 중 지정된 정보만 반환
getAllResponseHeaders() 모든 header 정보를 반환

 

 

 

AJAX 작동 순서

 

 

<!DOCTYPE html>
<meta charset="UTF-8">
<script>
    // 1. 통신을 위한 객체 생성
    let req = new XMLHttpRequest();

    // 2. 요청 정보 설정
    req.open("get", 'test.txt', true); // true(default이므로 생략 가능, 비동기로 작업)

    // 3. 요청 정보 서버로 전달
    req.send();

    // 4. 이벤트를 통해 응답 가능 상태 알림
    req.onreadystatechange = function(){
        console.log(req.readyState); // 2(요청 받음), 3(요청 처리 중), 4(요청 처리 완료 후 응답 준비) 출력
        if(req.readyState == 4 && req.status == 200){
            console.log( req.responseText ); // 요청을 받아서 콘솔에서 표현
        }
    }
</script>

 

결과 화면1

 

 

=> 일방적인 작성 순서

<!DOCTYPE html>
<meta charset="UTF-8">
<script>
    // 1. 통신을 위한 객체 생성
    let req = new XMLHttpRequest();

    // 2. 요청 정보 설정
    req.open("get", 'test.txt', true); // true(default이므로 생략 가능, 비동기로 작업)

    // 3. 요청 정보 서버로 전달
    // req.send(); // 처리되는 데이터의 양이 미미할 때
    
    // 4. 이벤트를 통해 응답 가능 상태 알림
    req.onreadystatechange = function(){
        console.log(req.readyState); // 2(요청 받음), 3(요청 처리 중), 4(요청 처리 완료 후 응답 준비) 출력
        if(req.readyState == 4 && req.status == 200){
            console.log( req.responseText ); // 요청을 받아서 콘솔에서 표현
        }
    }

    // 3. 요청 정보 서버로 전달
    // 요청에 대한 응답이 4번 항목의 처리보다 먼저 반환될 경우 상태코드가 누락될 가능성을 최소화하기 위해 3번을 가장 후순위로 처리한다.
    req.send();
</script>

 

 

 

AJAX 예제

 

 

dummy.txt

목캔디

 

 

ajax.csv

이름,나이,만화
아시타카,17,원령 공주
키키,13,마녀 배달부 키키
메이,4,이웃집 토토로
하울,27,하울의 움직이는 성

 

 

ajax.json

[
    {
        "name":"뽀로로", 
        "type":"펭귄", 
        "alias":"뽀롱뽀롱"
    },
    {
        "name":"크롱", 
        "type":"공룡", 
        "alias":"개구쟁이"
    },
    {
        "name":"루피", 
        "type":"비버", 
        "alias":"요리공주"
    },
    {
        "name":"에디", 
        "type":"여우", 
        "alias":"똑똑박사"
    }
]

 

 

ajax.xml

<!-- XML
데이터로 표현하는 마크업 언어의 하나
주로 서버 간 데이터 통신에 활용
html과 같이 시작태그와 종료태그로 값을 정의하고 속성값으로 추가정보를 부여 -->

<friends>
    <friend>
        <name>포비</name>
        <type>백곰</type>
        <alias>낚시왕</alias>
    </friend>
    <friend>
        <name>해리</name>
        <type>벌새</type>
        <alias>가수왕</alias>
    </friend>
    <friend>
        <name>로디</name>
        <type>로봇</type>
        <alias>척척박사</alias>
    </friend>
    <friend>
        <name>패티</name>
        <type>펭귄</type>
        <alias>춤신춤왕</alias>
    </friend>
</friends>

 

 

위치

예제가 있는 폴더 안에 폴더를 생성하여 넣어둔다.

 

 

  • ajax로 txt 출력
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button>ajax</button>
    <div>출력영역</div>

<script src="../js/jquery-3.7.1.min.js"></script>
<script>
    // 버튼 눌렀을 때 AJAX로 dummy.txt에서 제공하는 응답데이터를 화면상에 출력
    
    let v_btns = document.querySelectorAll('button');
    let v_disp = document.querySelector('div');

    v_btns[0].addEventListener('click', function(){
        let v_ajax = new XMLHttpRequest();
        v_ajax.open('get', 'ajax/dummy.txt', true);

        v_ajax.onreadystatechange = function(){
        // v_ajax.onload = function(){ // 위와 같이 사용 가능

        // v_ajax.onprogress = function(){ // 사용 불가능 : 3과 200을 출력
        // v_ajax.onloadstart = function(){ // 사용 불가능 : 1과 0을 출력

            // console.log("onload일때 >> ", v_ajax.readyState, v_ajax.status)
            if(v_ajax.readyState == 4 && v_ajax.status == 200) {
                v_disp.innerText = v_ajax.responseText;
            }
        }
        v_ajax.send();
    });

    // JQ 방식
    /* $('button').eq(0).on('click', function(){
        let v_ajax = new XMLHttpRequest();
        v_ajax.open('get', 'ajax/dummy.txt', true);

        v_ajax.onreadystatechange = function(){
            if(v_ajax.readyState == 4 && v_ajax.status == 200) {
                $('div').text(v_ajax.responseText);
            }
        }
        v_ajax.send();
    }); */

</script>
</body>
</html>

 

결과 화면2 : ajax 버튼 클릭 시 dummy.txt 내용 출력

 

 

 

  • ajax로 csv 출력
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button>ajax</button>
    <button>JSON가져오기</button>
    <div>출력영역</div>

<script src="../js/jquery-3.7.1.min.js"></script>
<script>
    // 버튼 눌렀을 때 AJAX로 dummy.txt에서 제공하는 응답데이터를 화면상에 출력
    
    let v_btns = document.querySelectorAll('button');
    let v_disp = document.querySelector('div');

    
    // CSV정보 AJAX로 가져오기
    // $('button').eq(0).on('click', function(){
    v_btns[1].addEventListener('click', function(){
        //1 XMLHttpRequest객체 생성
        let req = new XMLHttpRequest();

        //2 open(설정)
        req.open("get", "ajax/ajax.csv");

        //4 onreadystatechange readyState status responseText
        req.onreadystatechange = function(){
            if(req.readyState == 4 && req.status == 200) {
                console.log(req.responseText);
                f_csv(req.responseText);
            }
        }

        //3 send()
        req.send();
    });

    // css정보를 테이블 구조로 출력하기
    function f_csv(p_data) {
        // alert(p_data);
        let v_line = p_data.split("\r\n"); // 한 줄씩 정보 나누기

        let v_tbl = "<table border=1>";

        for(let i=0; i<v_line.length; i++) {
            v_tbl +="<tr>";
            let v_cell = v_line[i].split(",");
            console.log(v_cell);
            for(let j=0; j<v_cell.length; j++) {
                if(i<1) {
                    v_tbl += `<th>${v_cell[j]}</th>`;
                } else {
                    v_tbl += `<td>${v_cell[j]}</td>`;
                }
            }
            v_tbl += "</tr>";
        }
        v_tbl += "</table>";
        v_disp.innerHTML = v_tbl;
    }

</script>
</body>
</html>

 

결과 화면3 : CSV가져오기 버튼 클릭 시

 

 

 

  • ajax로 JSON 출력
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button>JSON가져오기</button>
    <div>출력영역</div>

<script src="../js/jquery-3.7.1.min.js"></script>
<script>
    // 버튼 눌렀을 때 AJAX로 dummy.txt에서 제공하는 응답데이터를 화면상에 출력
    
    let v_btns = document.querySelectorAll('button');
    let v_disp = document.querySelector('div');


    v_btns[0].addEventListener('click', function(){
        let req = new XMLHttpRequest();

        req.open('get', './ajax/ajax.json');

        req.onreadystatechange = function(){
            if(req.readyState == 4 && req.status == 200) {
                // console.log(req.responseText);
                //string 형태로 가기에 object로 보내줘야함
                // json문자열 => js객체로 변환
                let jsonObj = JSON.parse( req.responseText );
                f_json(jsonObj);
            }
        }
        req.send();
    });

    let f_json = function(p_json) {
        // alert(typeof p_json); // object인 객체로 전송됨
        console.log(p_json);
        let v_tbl = "<table border=1>";
        v_tbl += "<tr><th>이름</th><th>종류</th><th>별명</th></tr>"; // 제목 하드코딩

        for(let i=0; i<p_json.length; i++) {
            v_tbl += "<tr><td>" + p_json[i].name + "</td>";
            v_tbl += `<td>${p_json[i].type}</td>`;
            v_tbl += `<td>${p_json[i].alias}</td></tr>`;
        }
        v_tbl += "</table>";

        v_disp.innerText = ""; // 영역 초기화
        v_disp.insertAdjacentHTML('beforeend', v_tbl); // 추가
    };

</script>
</body>
</html>

 

결과 화면4

 

 

=> 제일 상단 하드코딩 대신 코드로 대체

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button>JSON가져오기</button>
    <div>출력영역</div>

<script src="../js/jquery-3.7.1.min.js"></script>
<script>
    // 버튼 눌렀을 때 AJAX로 dummy.txt에서 제공하는 응답데이터를 화면상에 출력
    
    let v_btns = document.querySelectorAll('button');
    let v_disp = document.querySelector('div');


    v_btns[0].addEventListener('click', function(){
        let req = new XMLHttpRequest();

        req.open('get', './ajax/ajax.json');

        req.onreadystatechange = function(){
            if(req.readyState == 4 && req.status == 200) {
                // console.log(req.responseText);
                //string 형태로 가기에 object로 보내줘야함
                // json문자열 => js객체로 변환
                let jsonObj = JSON.parse( req.responseText );
                f_json(jsonObj);
            }
        }
        req.send();
    });

    let f_json = function(p_json) {
        // alert(typeof p_json); // object인 객체로 전송됨
        console.log(p_json); // json object, js객체

        // 제목정보를 데이터의 key로 표시하기
        // Object라는 내장객체가 제공하는 keys(), values(), entries()
        let arrVal1 = Object.values(p_json)[0];
        console.log(arrVal1);
        let key = Object.keys(arrVal1);
        console.log(key);

        let v_tbl = "<table border=1>";
        // v_tbl += "<tr><th>이름</th><th>종류</th><th>별명</th></tr>"; // 제목 하드코딩
        v_tbl += `<tr><th>${key[0]}</th><th>${key[1]}</th><th>${key[2]}</th></tr>`;

        for(let i=0; i<p_json.length; i++) {
            v_tbl += "<tr><td>" + p_json[i].name + "</td>";
            v_tbl += `<td>${p_json[i].type}</td>`;
            v_tbl += `<td>${p_json[i].alias}</td></tr>`;
        }
        v_tbl += "</table>";

        v_disp.innerText = ""; // 영역 초기화
        v_disp.insertAdjacentHTML('beforeend', v_tbl); // 추가
    };

</script>
</body>
</html>

 

결과 화면5

 

 

 

  • ajax로 xml 출력
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button>XML가져오기</button>
    <div>출력영역</div>

<script src="../js/jquery-3.7.1.min.js"></script>
<script>
    
    let v_btns = document.querySelectorAll('button');
    let v_disp = document.querySelector('div');

    v_btns[0].onclick = function(){
        let ajax = new XMLHttpRequest();
        ajax.open('get', './ajax/ajax.xml', true);
        ajax.onreadystatechange = function(){
            if(this.readyState == 4 && this.status == 200) {
                // XML형식의 문자열 데이터는 접근이 어려움(정보를 얻기 힘듦)
                // XML은 HTML과 같이 태그로 이루어졌기 때문에 DOM API의 활용이 가능하다
                console.log(typeof this.responseXML); // object
                f_xml(this.responseXML);
            }
        };
        ajax.send();
    };

    function f_xml(p_xml){
        console.log(p_xml);
        let v_friends = p_xml.querySelectorAll('friend');
        console.log(v_friends);

        let v_tbl = "<table border=1>";
        for(let i=0; i<v_friends.length; i++) {
            v_tbl += `<tr>`;
            
            let child = v_friends[i].children;
            // console.log(v_friends[i].children[0].innerHTML);

            for(let j=0; j<child.length; j++) {
                v_tbl += `<td>${child[j].innerHTML}</td>`;
            }

            v_tbl += `</tr>`;
        }

        v_tbl += "</table>";

        v_disp.innerHTML = v_tbl;
    }

</script>
</body>
</html>

 

결과 화면6

 

 

반응형