[JavaScript] AJAX

aseol·2023년 11월 21일
0

JavaScript

목록 보기
15/15

AJAX

Asynchronous Javascript And XML.
: 비동기식 자바스크립트 XML
XML에 기반으로 하여 서버와의 통신을 비동기 방식으로 연결함으로써 시스템 자원의 불필요한 시간낭비를 줄이고 사용자 환경은 자바스크립트가 지원하는 대화형 웹 Application을 구현한 기술이다. 한마디로 웹 브라우저와 웹 서버가 내부적으로 데이터 통신을 하게 됨으로써 변경된 결과를 웹 페이지에 프로그래밍적으로 반영하여 웹 페이지의 로딩 없이 서비스를 사용할 수 있게 해 주는 것이다 ➡️ 매번 새로고침을 하지 않아도 된다!

특징

  • 브라우저가 가지고 있는 XMLHttpRequest 객체를 활용하여 비동기화 통신
  • 페이지를 새로고침 및 전환할 필요 없이 자바스크립트로 서버와 통신
  • 서버 처리를 기다리지 않고, 비동기 요청이 가능
  • 수신하는 데이터 양을 줄일 수 있고, 클라이언트에게 처리를 위임 가능

동기화 VS 비동기화

동기

: 데이터의 요청과 결과가 한 자리에서 동시에 일어나는 방식

  • 요청을 하면 요청한 자리에서 결과가 주어져야 한다.
  • 작성된 코드 순서대로 처리를 완료하고 이후에 클라이언트에 응답하는 방식
    ➡ 서버에서 응답이 늦어질 경우 클라이언트에서 화면 출력을 대기하는 시간이 길어진다.

비동기

: 데이터의 요청과 결과가 한 자리에서 동시에 일어나지 않는 방식

  • 웹페이지를 리로드하지 않고 서버와 통신할 수 있다.
  • 페이지 전체를 로드하여 렌더링할 필요가 없고 갱신이 필요한 일부만 로드하여 갱신하면 된다.
    ➡ 클라이언트에서 호출 후 기다리지 않고 서버에서 응답시 작성된 코드가 실행

비동기 통신 요청과 응답

요청 : 서버상에 존재하는 URL을 호출
응답 : 서버에서 응답한 데이터를 클라이언트에게 전달 (데이터를 가공하여 화면에 출력)

  • 응답데이터 포맷은 주로 JSON(JavaScript Object Notation)을 사용
  • 브라우저에서 표현 가능한 대표적인 포맷 방식 : html, xml, json, text
  • contentType (MIME-TYPE) :
    html ➡ text/html
    xml ➡ application/xml
    json ➡ application/json
    text ➡ text/plain

    💡JSON(JavaScript Object Notation)
    데이터를 저장하고 교환하기 위한 경량의 데이터 형식. 텍스트 형식으로 구성되며, 사람과 기계 모두 이해하기 쉽고 파싱하기 쉽기 때문에 데이터 교환 및 저장에 매우 효율적으로 사용된다.

promise 표준 내장 객체

The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

  • 자바스크립트 비동기 처리에 사용되는 객체

  • 전통적인 방식에선 비동기 처리를 위해 콜백 함수를 사용했지만 콜백 패턴은
    콜백 헬로 인해 가독성 및 에러 처리(예외 처리)가 곤란
    ➡ 대안으로 ES6에서는 비동기 처리를 위한 또 다른 패턴인 promise를 도입

  • 프로미스의 3가지 상태(states)

    - 🟢 Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태

    - 🟢 Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태

    - 🟢 Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

    생성자 🔽

    참조변수 = new Promise ( excutor ) ;
    excutor : Promise의 생성자 함수가 인자로 받는 콜백함수로, resolve 및 reject 인수를 전달할 실행 함수이다.

    메소드 🔽

    Promise.prototype.then()

    Promise.prototype.then(onFulfilled, onRejected) :
    Promise 를 리턴하고 두 개의 콜백 함수를 인수로 받는다.

1. onFulfilled : Promise가 수행될 때 호출되는 Function으로, 
이행 값(fulfillment value) 하나를 인수로 받는다.
>
2. onRejected : Promise가 거부될 때 호출되는 Function으로, 
거부 이유(rejection reason) 하나를 인수로 받는다.

fetch 전역 함수

서버에 네트워크 요청을 보내고 새로운 정보를 받아오는 일을 수행
구문 🔽

fetch(resource, options)

option에 아무것도 넘기지 않으면 요청은 GET 메소드로 진행(기본이 get 방식!)

fetch() : let promise = fetch(url, [option]);

- 응답시 단계<br>
- 1단계 : 서버에서 응답헤더를 받자마자 fetch호출 시 반환되는 promise가 내장 클래스 Response의 인스턴스와 함께 이행<br>
-       (아직 본문(body) 도착하기 전 상태, 개발자는 응답 헤더를 보고 요청이 성공적으로 처리되었는지 아닌지 확인)<br>
-       (http 상태는 응답 프로퍼티를 사용해 확인 status: http상태코드, ok: 불린값 http상태코드가 200~299사이일 경우 true)<br>
- 2단계 : 추가 메서드를 호출해 응답 본문을 받음<br>
- response.text() : 응답을 읽고 텍스트 반환<br>
- response.json() : 응답을 JSON 형태로 파싱<br>
- response.formData() : 응답을 FormData 객체 형태로 반환<br>
- response.blob() : 응답을 Blob(타입이 있는 바이너리 데이터)형태로 반환<br>
- response.arrayBuffer() : 응답을 ArrayBuffer(바이너리 데이터를 로우레벨 형식으로 표현한것) 형태로 반환<br>

Axios

브라우저와 node.js에서 사용할 수 있는 Promise 기반 HTTP 클라이언트 라이브러리
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])

jQuery ajax

jQuery 에서 지원하는 비동기 통신을 위한 메소드
요청 후 성공 및 실패에 관하여 메소드 체이닝 제공
jqXHR.done(function( data, textStatus, jqXHR ) {})
jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {})

공공데이터 (기상청_단기예보 (()_동네예보) 조회서비스) 받아 와서 화면에 나타내기 
function paramFn(date){
            // base time : 발표 시각, fcst time : 예보 시각
            let baseDate = date.format('YYYYMMDD'); // 오늘 날짜 // format 사용하면 원하는 형태로 바꿀 수 있다
            let baseTime = Number(date.format('HHmm')); // 현재 시각 
            
            //api 요청 시간에 따른 base_time 조정
            if(baseTime > 2310){
                baseTime = '2300';
            }else if(baseTime > 2010){
                baseTime = '2000';
            }else if(baseTime > 1710){
                baseTime = '1700';
            }else if(baseTime > 1410){
                baseTime = '1400';
            }else if(baseTime > 1110){
                baseTime = '1100';
            }else if(baseTime > 810){
                baseTime = '0800';
            }else if(baseTime > 510){
                baseTime = '0500';
            }else if(baseTime > 210){
                baseTime = '0200';
            }else{
                baseDate = date.subtract(1,'d').format('YYYYMMDD');
                baseTime = '2300';
            }

            console.log(`${baseDate} || ${baseTime}`);
            const param = {
                'serviceKey': 'mv7LN8a+C77voB3VWpzfojItcXghnxs/LfzIRH6YUkUOUF3mnGZi4+QAgOXaINJ2oyHKFkNnAT1ztVWe3wX/sQ==',
                'pageNo': '1',
                'numOfRows': '60',
                'dataType': 'JSON',
                'base_date': baseDate,
                'base_time': baseTime,
                'nx': '63',
                'ny': '89'
            }
            return param;
        }






        $('#exAjax').click(function () {

            // moment() : JavaScript에서 날짜와 시간을 다루기 위한 라이브러리인 "moment.js"의 함수 중 하나로, 
            이 함수를 사용하면 현재 시간을 나타내는 moment 객체를 생성할 수 있다.       
            const paramObj = paramFn(moment());

            const request = $.ajax({
                url: "https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getVilageFcst",
                method: "GET",
                data: paramObj,
                dataType: "JSON"
            });
            request.done(function(response){
                const dataList = response.response.body.items.item;
                // 현재 날짜와 현재 시간 가져오기 
                const currentDate = moment().format('YYYYMMDD');
                const currentTime = moment().add(1,'h').format('HH00'); // add(더할 시간(숫자), '더할 시간 단위') ex. add(10,'m') : 10분 더함
                const castDateTime = moment(`${currentDate} ${currentTime}`).format('YYYY년 MM월 DD일 HH시 mm분 기준');
                //console.log(response);
                console.log(currentDate);
                console.log(currentTime); 
                console.log(castDateTime);
                //console.log(moment(`mom ${currentDate} ${currentTime}`));
                console.log(dataList);
                const fcstObj = {'예보 기준' : castDateTime} // 예보 
                console.log(fcstObj);

                dataList.reduce((acc, cur) => {
                    if(cur.fcstDate == currentDate && cur.fcstTime == currentTime){
                        
                            // 현재기온(TMP ℃), 강수확률(POP %), 습도(REH %), 하늘상태(SKY  ➡ 하늘상태(SKY) 코드 : 맑음(1), 구름많음(3), 흐림(4))
                            switch(cur.category){
                                case 'TMP' :
                                     acc['현재기온'] = cur.fcstValue + '℃';
                                     break;
                                case 'POP' : 
                                     acc['강수확률'] = cur.fcstValue + '%';
                                     break;
                                case 'REH' : 
                                     acc['습도'] = cur.fcstValue + '%';
                                     break;
                                case 'SKY' : 
                                     let codeNumber = Number(cur.fcstValue);
                                     if(codeNumber == 1){
                                        acc['하늘상태'] = '맑음';
                                     }else if(codeNumber == 3){
                                        acc['하늘상태'] = '구름많음';
                                     }else{
                                        acc['하늘상태'] = '흐림';
                                     }
                                     break;
                            }
                        }
                       return acc;     
                }, fcstObj);
                console.log(fcstObj);
                $('#curDate').val(fcstObj['예보기준']);
                $('#curTemp').val(fcstObj['현재기온']);
                $('#curSky').val(fcstObj['하늘상태']);
                $('#proRain').val(fcstObj['강수확률']);
                $('#humidity').val(fcstObj['습도']);
            });

            request.fail(function (jqXHR, textStatus) {
                alert("Request failed: " + textStatus);

            });
        });


참조
https://axios-http.com/kr/docs/intro

1개의 댓글

comment-user-thumbnail
2023년 11월 22일

안녕하세요 :) 국비지원 부트캠프 엘리스트랙입니다! 오늘도 개발 공부 열심히 하고 계시군요! 멋지십니다 :)
혹시 신입으로 개발 공부하면서 기술면접에 대한 대비가 막막하시다면, 이번 기술면접 특강도 관심 가져보시면 좋을 것 같아 댓글로 행사 안내드려요~

프론트/ 백엔드 모두 실력있고, 실제 면접관으로 활동하고 계신 개발자 코치님께서 진행하시니 참여해 보세요> https://festa.io/events/4389

그럼 오늘도 화이팅입니다!🙇🏻‍♀️💪🏻

답글 달기