mjeongriver
article thumbnail
Published 2023. 1. 6. 18:14
day62-js TIL/Javascript

1. 자바스크립트 비동기 AJAX

- AJAX ( Asynchronous Javascript and XML) 은 웹 페이지의 이동없이 필요한 데이터만 전송하는 기술입니다. 일반적인 경우 데이터 처리는 요청 순서대로 진행하지만 AJAX는 순차적으로 진행하지 않습니다.

이런 방식을 비동기 방식 이라고 합니다.

자바스크립트의 비동기 방식은 상당히 까다로운데, 이를 간단히 사용할 수 있게 해주는 최신 자바스크립트 API인 fetch API를 이용하도록 하겠습니다.

 

- API가 뭔가요? (application programming interface)

우리 기능을 사용 할려면 너는 x1, x2, x3, x4, x5 .... x100을 처리해야해 하지만 너무 어렵고 많은 것을 해야 하잖아? 그럼 우리가 사용 방법을 정의 해서 줄게 너는 이렇게 사용해!

 

 

* 예제

 

- 5번째 사진 보면 fetch는 비동기 방식이기 때문에 실행이 완료될 때까지 기다리지 않고 다음을 실행하고 넘어감. 그래서 순서가 1, 3, 2 이렇게 됨. 순서가 항상 고정되지 않음

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

</head>

<body>

    <button onclick="ajax()">ajax 요청</button>

    <script>

        /* 
        비동기 - 웹페이지 이동 없이 데이터만 주고 받는 기술
        fetch()를 호출하면 promise를 반환
        
        promise 
        - pending: 수행 중
        - fullfiled: 성공
        - reject: 실패

        1. promise 객체에는 then이라는 함수를 사용할 수 있습니다.
        (return이 promise라면 then(콜백 함수)로 결과를 받을 수 있습니다.)
        */


        /* 1nd 
         function ajax(){
             var result = fetch("hi.txt") //url 주소 개발자 도구로 console.log(result) 찍으면 promise 객체 
             result.then(function(response) {
                 console.log(response);
             }) //(function(response) {}): 호출 했을 때 결과를 돌려받을 함수
         } 
         */


        //줄여서 써도 위와 결과는 같습니다.
        /*  2nd
        fetch("hi.txt").then(function (response) { //fetch("hi.txt")의 실행 결과가 promise
             // console.log(response);
             if (response.status != 200) {
                 alert("통신에 에러가 발생했습니다.");
                 return;
             }
 
             // var a = response.text(); 
             // console.log(a); //프로미스
             response.text().then(function (data) { //비동기 방식이라 화면 이동은 없음
                 console.log(data);
             });
         }); 
         */

        /* 3nd - 콜백에 리턴을 걸면 fetch가 다시 promise를 반환(위에 연쇄적으로 function 하는 것보다 밑에 처럼 써야 보기 좋은 코드가 됩니다.)
            fetch("hi.txt")
            .then(function (res) {
                return res.text(); //콜백에 걸린 return이 fetch에 걸린 return으로 돌아가게 되어있음
            }).then(function(data) {
                return data;
            }).then(function(data) {
                console.log(data);
            }); 
        */

        //4nd - 비동기 방식에서는 순서를 보장하지 않음
        console.log(1);

        fetch("hi.txt")
        .then(function(res) {
            return res.text();
        })
        .then(function(data){
            console.log(2);
        });

        console.log(3);
        
    </script>

</body>

</html>

 

2. json

JSON(JavaScript Object Notation)은 자바스크립트 객체로 구성된 데이터 입니다. 자바스크립트 객체 형태의 문자열인 셈입니다.

서블릿(서버) 에서 AJAX로 응답할 때 객체를 어떻게 줄 것인가?

방법이 있는가?

그렇다면 JSON형태의 문자열로 응답해 줄테니 받아서 쓰세요!

ex) {키 : 값, 키 : 값, 키 : [배열] }

그렇다면 서버에서는 JSON을 이용해서 어떻게 응답할 수 있는가?

1) JSON객체를 지원해주는 라이브러리가 필요합니다. (JSON-SIMPLE 라이브러리)

2) response객체의 설정을 JSON형식 으로 지정합니다

 

꼭 쌍따옴표로 묶어줄 것(숫자는 안해줘도 됨)

 

 

* index02, hi.json, hi.xml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <button onclick="ajax()">json 파일 ajax 요청</button>

    <!-- script가 아래에 있기 때문에 화면이 먼저 그려짐 -->
    <div class = "result">

    </div>
    
    <script>
        function ajax(){
            fetch("hi.json")
            .then(function(res) {
                return res.json(); //json형변환
            })
            .then(function(data) {
                // console.log(data);
                // console.log(data.id); //ok
                // console.log(data["id"]); //ok
                var result = document.querySelector(".result");
                result.innerHTML = data["id"];
            })
        }
    </script>

    <button onclick="ajax2()">xml 데이터 ajax 요청</button>

    <script>
        function ajax2() {
            fetch("hi.xml")
            .then(function(res){
                return res.text();
            })
            .then(function(data) {
                
                var result = new DOMParser().parseFromString(data, "text/xml")
                
                //console.log(result.querySelector("datas"));

                var arr = result.querySelectorAll("datas > data");
                for(var i = 0; i < arr.length; i++){
                    console.log(arr[i].querySelector("name") );
                    console.log(arr[i].querySelector("version") );
                    console.log(arr[i].querySelector("price") );
                }
            })
        }

    </script>

</body>
</html>
{
    "id" : "kkk123", 
    "topic" : "ㅎㅎ..", 
    "age" : 20
}
<?xml version="1.0" encoding="UTF-8"?> 
    <datas> 
        <data> 
            <name>Windows</name> 
            <version>9</version> 
            <price>99</price> 
        </data> 
        <data> 
            <name>Mac</name> 
            <version>15</version> 
            <price>99999</price> 
        </data> 
        <data> 
            <name>Linux</name> 
            <version>123.4567</version> 
            <price>0</price>
        </data> 
    </datas>

국가데이터포털 - end point: 접속할 수 있는 주소

 

- pageNo = 변경하면 다른 페이지의 정보를 읽을 수 있음

 

* ajax 서버 예제

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <ul class="pageNation">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>

    <script>
        var key = 여기에는 승인 받은 인증키를 넣습니다.

        var pageNation = document.querySelector(".pageNation");
        pageNation.onclick = function () {

            if(event.target.tagName != "LI") return;
            ajax(event.target.innerHTML); //데이터 호출(사용자가 클릭한 페이지 번호), 괄호에 매개변수 호출
        }

        function ajax(page) { //page 누른 값

            fetch("http://apis.data.go.kr/1360000/TourStnInfoService/getTourStnVilageFcst?serviceKey=" + key + "&pageNo=" + page + "&numOfRows=10&dataType=JSON&CURRENT_DATE=2023010600&HOUR=24&COURSE_ID=1")
                .then(function (res) {
                    return res.json();
                })
                .then(function (data) {
                    //console.log(data.response);
                    var arr = data.response.body.items.item;
                    for (var i = 0; i < arr.length; i++) {
                        console.log(arr[i]);
                    }
                })
        }

        (function() {
            ajax(1);
        })();

    </script>
</body>

</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>
        .list {
            display: flex;
            flex-wrap: wrap;
            margin: 0 auto;
            width: 100%;
        }
        .movie {
            
            flex-basis: 100px;
            padding: 20px;
        }
    </style>
    
</head>

<body>

     <div class ="list">
        <!--
        <div class = "movie">
            <img class ="img" src = "#">
            <p class = "title"></p>
        </div> -->
    </div> 

    <script>
        fetch("https://yts.mx/api/v2/list_movies.json")
            .then(function (res) {
                return res.json();
            })
            .then(function(data) {
                var arr = data.data.movies;

                var str = ""; //화면을 그릴 문자열

                for (var i = 0; i < arr.length; i++) {
                    // console.log(arr[i]);
                    var img = arr[i].medium_cover_image;
                    var title = arr[i].title;

                    str += '<div class="movie">';
                    str += '<img class="img" src="' + img + '">';
                    str += '<p class="title">' + title + '</p>';
                    str += '</div>';
                }

                //innerHTML
                document.querySelector(".list").innerHTML = str;
            })

    </script>
</body>

</html>

 

여기에 있는 주소를 카카오 api에서 2번째 사진 아래에 추가
다른 이름으로 저장해서 폴더 내에 넣을 것, javaScript 키

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 카카오 sdk 로드 -->
    <script src="js/kakao.min.js"></script>
</head>

<body>

    <a id="kakao-login-btn" href="javascript:loginWithKakao()">
        <img src="https://k.kakaocdn.net/14/dn/btroDszwNrM/I6efHub1SN5KCJqLm1Ovx1/o.jpg" width="222" alt="카카오 로그인 버튼" />
    </a>

    <script>

        //1. 카카오 sdk 초기화
        Kakao.init('9629685bfbcc70031260bf6e46d4cdb8');
        Kakao.isInitialized();
        console.log(Kakao.isInitialized());

        //2. 
        function loginWithKakao() {
            Kakao.Auth.authorize({
                redirectUri: 'http://127.0.0.1:5501/09Ajax/index05.html',
            });
        }

    </script>


</body>

</html>

'TIL > Javascript' 카테고리의 다른 글

day64-JS ES6 문법  (0) 2023.01.12
day63-js  (0) 2023.01.09
day61-js  (0) 2023.01.05
day60-js  (0) 2023.01.04
day59-js  (1) 2023.01.03
profile

mjeongriver

@mjeongriver

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그