Ajax
Ajax란?
AJAX는 Asynchronous JavaScript and XML의 약자로, 말 그대로 JavaScript와 XML을 이용한 비동기적 정보 교환 기법입니다.
이름에 XML이라고 명시되어있긴 하지만 JSON이나 일반 텍스트 파일과 같은 다른 데이터 오브젝트들도 사용 가능해서 요즘엔 XML을 잘 안 쓰고 십중팔구 JSON을 다룬다고 합니다. 용어와 실제 기술 간의 차이가 커져서 요즘에는 약어가 아닌 고유명사 취급하고 있습니다.
Ajax는 빠르게 동작하는 동적인 웹 페이지를 만들기 위한 개발 기법의 하나입니다.
Ajax는 웹 페이지 전체를 다시 로딩하지 않고도, 웹 페이지의 일부분만을 갱신할 수 있습니다.
즉 Ajax를 이용하면 백그라운드 영역에서 서버와 통신하여, 그 결과를 웹 페이지의 일부분에만 표시할 수 있습니다.
어떻게 사용되는지 예시를 보여드리겠습니다.
예시
비교를 위해서 동기처리와 비동기 처리 두 가지를 비교하여 보여드리겠습니다.
동기처리(Synchronization Processing)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>step1-syn</title>
</head>
<body>
<div>
<form action="SynServlet">
<input type="text" name="userId" required="required" placeholder="고객 아이디">
<button type="submit">동기테스트</button>
</form>
<br><br>
<textarea rows="25" cols="50" placeholder="본문내용"></textarea>
</div>
</body>
</html>
동기처리를 보시면
이렇게 글을 쓰고 있는데 고객 아이디를 확인해야하는 버튼을 미리 눌러야 하는데 누르지 못하고 본문을 작성한 상황을 가정하겠습니다.
하지만 저 버튼이 비동기처리가 아닌 동기처리면.... 새로운 페이지를 받아서 자신이 작성했던 글을 날려먹을 수도 있는 상황이 나오게 됩니다. (이 페이지는 SynServlet을 통해 생성된 페이지입니다.)
자신이 작성하던 페이지가 사라지니 여간 불편한 게 아닙니다. 그래서 이럴 때 비동기 처리를 하여 기존의 작업에 방해를 안 가게 해야 합니다. 보실까요?
비동기 처리(asynchronous processing)
Javascript로 작성되어 조금은 복잡해 보이지만 천천히 한 줄 한줄 알아가 볼까요?
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>step2-asyn</title>
</head>
<body>
<div>
<form action="AsynServlet">
<input type="text" id="userId" required="required"
placeholder="고객 아이디">
<button type="button" onclick="startAjax()">비동기테스트</button>
<%-- ajax 응답 --%>
<span id="result"></span>
</form>
<br> <br>
<textarea rows="25" cols="50" placeholder="본문내용"></textarea>
<script type="text/javascript">
let xhr;
function startAjax() {
xhr = new XMLHttpRequest(); //Javascript 통신을 위한 객체 ( Ajax 통신 담당 객체 )
//서버에서 응답하면 동작될 함수를 지정 : 익명함수 (anonymous function) 방식으로 구현
xhr.onreadystatechange = function(){ //callback 익명 함수 : 서버에서 응답완료되고 정상 수행되면 실행될 함수
// 4: 응답 완료, 200: 정상수행
if (xhr.readyState === 4 && xhr.status === 200) {
//서버가 응답한 데이터 : xhr.responseText
document.getElementById("result").innerHTML = xhr.responseText;
}else if(xhr.readyState<4){//응답 완료전까지는 움직이는 아이콘을 제공
//0~3 요청 진행중인 상태 (응답완료전 상태)
document.getElementById("result").innerHTML = "<img src=working.gif>";
}
}
let id = document.getElementById("userId");
xhr.open("get", "AsynServlet?id=" + id.value);
xhr.send();
}
</script>
</div>
</body>
</html>
script 태그에 있는 코드를 해석해 보아요.
1. 버튼을 누르면 startAjax() 함수를 실행되게 합니다.
2. XMLHttpRequest(); 객체를 생성합니다.
-> Javascript 통신을 위한 객체 생성입니다. (Ajax 통신 담당 객체)
3. xhr.onreadystatechange
-> 서버에서 응답하면 동작될 함수를 지정합니다.
4. 응답하면 동작될 함수 분석
-> if(xhr.readystate ===4 && xhr.status ===200)의 뜻은 응답완료하고 정상수행되었다면입니다.
else if(xhr.readyState <4)의 뜻은 응답 완료 전까지는 readystate가 4 이하입니다.
readyState 값의 의미
- 0: uninitialized(초기화되지 않음)
- 1: loading(로드 중)
- 2: loaded(로드됨)
- 3: interactive(대화형)
- 4: complete(완료됨)
5. document.getElementById("result"). innerHTML = xhr.responseText;
-> result라는 아이디를 가진 태그 innerHTML에 응답으로 온 text를 넣어주어라 라는 뜻입니다. (밑에 else if 문은 이미지를 넣어준 것입니다.)
6. xhr.open("get", "AsynServlet? id=" + id.value);
-> http 메서드와 url을 작성해 주면서 어떠한 방식과 위치로 요청을 보내는지 작성합니다.
7. xhr.send()
-> 요청을 보내줍니다.
이렇게 되면 결과
아무리 눌러도 화면이 변화하지 않습니다.
서버는 Java로 만들었는데
동기 처리 시에는 페이지 전부를 작성하여 보내줘야하고 (html, head, body 등등)
비동기 처리시에는 필요한 내용만 작성하여 보내주면 됩니다.
@WebServlet("/AsynServlet")
public class AsynServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private int count = 0;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String id = request.getParameter("id");
count++;
System.out.println("client 에서 전송받은 id : " + id + " " + count);
out.print(id + "님 ajax 응답!" + " " + count);// ajax 통신이므로 페이지가 아니라 필요한 데이터만 응답
out.close();
}
}
이런 식으로 저렇게 String 만 보내주면 됩니다.
소감
여러 가지 처리를 위해 동기와 비동기처리를 잘 조화해서 사용해야겠습니다.
오늘도 좋은 글 하나 남기고 가겠습니다.
영림그룹 회장님 강연 노트입니다. 안 되는 일은 하지 말고 되는 일을 하자입니다. 더 많은 내용이 있으니 한 번 읽어보면 좋을 것 같습니다.
https://m.blog.naver.com/ps_4/223121948419
그리고 다음시간에는 json 관련 글도 남겨보겠습니다.