본문 바로가기
스터디/Server

비동기 상호작용이란?

by SayHiWorld 2024. 8. 27.

 

package com.example.demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class NoParameterAjaxRestController {
    @RequestMapping ("/get-with-no-param")
    public String getWithNoParameter(){
        return "파라미터가 없는 GET 요청";
    }
}

서버와의 비동기 상호작용은 쉽게 말해

'웹 페이지를 새로 고침하지 않고 서버로 정보를 보내거나 서버의 정보를 가져오는 것'을 의미한다. 

 

그 예시로는 유튜브에서 스크롤을 내리는 것을 생각해볼 수 있다. 

유튜브 홈화면에 접속해서 스크롤을 내리다보면, 하단에 도달했을 때 로딩 아이콘이 뜨면서 다음 영상들이 뜨는 것을 볼 수 있다.

웹 페이지 새로 고침을 따로 누르지 않았는데, 서버로부터 정보를 받아왔다. 

 


 

AJAX는 Asynchronous(비동기) JavaScript And XML의 약자이다.

이름에는 XML이 붙어 있지만, JSON을 사용해도 무관하다. (현재에는 JSON을 사용하여 통신하는 경우가 더 많다.)

 

자바스크립트를 통해 서버로 비동기로 요청하는 것을 의미한다. 

 

서버와 비동기로 상호작용하는 것을 확인하기 위해서는 다음과 같은 코드를 작성한다.

1. 클라이언트 코드 : HTML 페이지 내에 XHR을 사용하여 서버로 AJAX 요청을 하는 코드

(XHR 은 AJAX요청을 생성하는 javascript 코드이다.)

2. 서버 코드 : AJAX 요청에 대한 간단한 응답을 하는 컨트롤러 코드

 


클라이언트 코드

 

클라이언트 코드는 resources - static 폴더에 작성한다.

아래와 같이 html 코드를 작성하였다.

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <script>
        //1번 영역//
            function onReadyStateChange(event){
                if(ajaxRequest.readyState === XMLHttpRequest.DONE){
                    if(ajaxRequest.status === 200){
                        console.log(ajaxRequest.responseText);
                    } else {
                        console.error('request failed');
                    }
                }
            }
            //1번 영역//
			
            //2번 영역//
            const ajaxRequest = new XMLHttpRequest();

            ajaxRequest.onreadystatechange = onReadyStateChange;
            ajaxRequest.open('GET','get-with-no-param');
            ajaxRequest.send();
            //2번 영역//
        </script>
    </body>
</html>

 

1번 영역에는 onReadyStateChange()라는 함수 선언이 있고, 2번 영역에는 ajaxRequest의 onreadystatechange라는 변수에 저장된다.

 

onreadystatechange는 이벤트 핸들링을 위한 필드 중 하나이다.

(onerror, onload, ontimeout 등등이 있는데.. 개발 도중 필요할 때 찾아보면 된다)

 

이렇게 하면 onReadyStateChange()라는 함수는 ajaxRequest에서 onreadystatechange가 발생했을 때 호출된다.

 

우리는 '이벤트 핸들러' 라는 용어를 써서 특정 이벤트가 발생했을 때 호출되는 함수를 지칭한다.

여기서 이벤트란 애플리케이션 상에서 발생할 수 있는 어떠한 사건을 이야기한다.

예를 들어 사용자가 마우스로 클릭하는 것도 하나의 이벤트이다. (이때는 onclick 이벤트를 사용한다)

 

이 상황에서는 onReadyStageChange()를 ajaxRequest.onreadystatechange의 이벤트 핸들러로 등록했다고 표현한다.

여기서는 ajaxRequest의 readyState가 change 되는 것이 이벤트이다. 

 

>ajaxRequest의 readyState는 다음과 같은 상태를 가질 수 있다.

상태 설명
UNSENT 0 XHR 객체가 생성된 후 open()함수를 호출하지 않은 상태
OPENED 1 open() 함수가 호출되지 않은 상태. open()함수는 초기 설정 함수이다.
HEADERS_RECEIVED 2 send() 함수가 호출된 상태 또는 HTTP 응답 헤더와 상태 코드까지만 사용할 수 있는 상태
LOADING 3 HTTP 응답의 body를 다운로드하고 있는 상태
DONE 4 XHR 객체의 AJAX 요청과 응답이 모두 완료된 상태 

 

 

즉, if (ajaxRequest.readyState === XMLHttpRequest.DONE) 은

if (ajaxRequest.readyState === 4) 와 동일하다. 그렇지만 위 코드처럼 작성하는 것이 코드의 가독성을 높여줄것이다.

 

그렇다면 onReadyStateChange() 함수는 몇 번이나 실행될까?

readyState가 변할때마다 호출되는 것을 생각하면, XHR 객체는 최초 생성때부터 시작하여 다음과 같이 변했다.

UNSENT -> OPENED -> HEADERS_RECEIVED -> LOADING -> DONE 의 순서로 변경되므로

총 4번 호출되었다. 

물론, readyState가  DONE일때만 실제 내부 코드 블록들을 실행키도록 하는 if문이 있다. 

 


서버 코드

 

아래는 java 폴더에 들어갈 서버 코드이다.

클라이언트 측에서 get-with-no-param이라는 페이지를 GET요청하였으니

서버 측 코드는 컨트롤러를 새로 만들어 아래와 같이 작성하였다.

package com.example.demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class NoParameterAjaxRestController {
    @RequestMapping ("/get-with-no-param")
    public String getWithNoParameter(){
        return "파라미터가 없는 GET 요청";
    }
}

 


지금까지 살펴본 코드는 AJAX의 원리를 이해하기 위한 예제 코드였다. 

이어서 JSON을 주고 받는 좀 더 실용적인 형태의 AJAX 활용 코드를 살펴보자.