- Today
- Total
개발하는 고라니
[Javascript] Ajax 본문
Ajax
Ajax이전의 웹 요청은 문서요청이라서 매 요청마다 문서를 새로 받아왔다. 웹 개발을 하다보면 페이지를 새로고침 없이 데이터를 받아오거나, 데이터를 보내거나 등 작업이 요구될 때가 많은데 이같은 작업을 위해선 비동기적인 방법이 필요하다.
Ajax(Asynchronous Javascript and XML)은 Javascript 라이브러리 중 하나이다. 비동기식 요청의 대표적인 라이브러리이다. 브라우저가 갖는 XMLHttpRequest 객체를 이용해 페이지를 다시 요청(Refresh)하지 않아도 데이터를 가져올 수 있는 기술이기도 하다. Javascript를 이용한 비동기 통신, 클라이언트와 서버간 XML 데이터를 주고받는다.
데이터 전송
Ajax를 알아보기 전에 동기식과 비동기식 데이터 전송은 어떻게 다른가에 대해 짚고 가보고자 한다.
※ 동기식 데이터 전송
동기화란 사전적 의미로 '작업들 사이의 수행 시기를 맞추는 것. 사건이 동시에 일어나거나, 일정한 간격을 두고 일어나도록 시간의 간격을 조정하는 것'을 말하는데, 웹 화면 구성에서의 동기화란 위의 그림처럼 서버로 데이터를 요청하고 응답이 오는 시간동안 작업을 멈추고 기다리는 것을 뜻한다.
※ 비동기식 데이터 전송
Ajax는 비동기식으로 데이터 전송을 하는데 서버로 데이터를 요청하고 응답을 기다리는 동안 웹은 자신의 업무를 계속 수행하고 응답이 오면 그때 처리한다. 결과적으로 페이지를 다시 요청하는 일도 없고, 요청-응답 사이 시간에 다른 일을 진행할 수 있기 때문에 편리하고 빠르게, 또 동적으로 작업을 처리하는 것 처럼 느낄 수 있다.
데이터의 형식
Ajax 통신에서 데이터를 전송하는 형식은 크게 3개로 꼽을 수 있다. CSV, JSON, XML 형식이다.
CSV
title,content,writer,name
나는고양이,안녕하세요,김작가,김작가
------------------------------------------------
년,월,일,온도,습도,미세먼지,초미세먼지
2021,4,29,10,100,5,19
------------------------------------------------
이름,나이,성별,ID
gorany,24,남,gorany111
위는 CSV의 예시이다. ','(콤마)로 구분되어있고 줄바꿈으로 데이터를 나눈다. 용량은 적으나 가독성이 떨어진다.
XML
<?xml version="1.0" encoding="UTF-8"?>
<shop city="서울" type="마트">
<food>
<name>귤</name>
<sort>과일</sort>
<cost>3000</cost>
</food>
<food>
<name>상추</name>
<sort>야채</sort>
<cost>2000</cost>
</food>
</shop>
<> 꺽쇠로 구분되어진 문서. CSV 형식의 가독성을 개선하기 위해 나온 데이터 형식. 가독성은 좋지만 데이터가 많아지면 분석 속도가 저하된다.
JSON
{
"name": "식빵",
"family": "웰시코기",
"age": 1,
"weight": 2.14
}
JSON(Javascript Object Notation) 형식은 자바스크립트 객체 형태로 데이터를 전송한다. XML 형식과 CSV 형식의 단점을 최소화한 형식으로 가장 널리 쓰인다.
Ajax의 장점과 단점
※ 장점
- 웹 페이지의 속도 향상
- 서버의 처리가 완료될 때 까지 기다리지 않고 처리가 가능
- 서버에서 데이터만 전송하면 되므로 전체적인 코드량이 줄어듬
- 기존 웹에서 불가능했던 다양한 UI를 가능하게 함
※ 단점
- 히스토리 관리가 되지 않음
- 페이지 이동없는 통신으로 보안상의 문제가 될 수 있음
- 연속으로 데이터를 요청하면 서버 부하 증가할 수 있음
- XMLHttpRequest를 통해 통신하는 경우, 사용자에게 아무런 진행 정보가 주어지지 않음
- 요청이 완료되지 않았는데, 사용자가 페이지를 떠나거나 오작동할 우려가 발생
- Ajax를 사용할 수 없는 브라우저에 대한 문제 이슈
- HTTP 클라이언트의 기능이 한정되어있음
- 지원하는 Charset이 한정되어있음
- 디버깅이 용이하지 않음
- 다른 도메인과는 통신이 불가능 (Cross-Domain 문제)
Ajax의 진행 과정
1) XMLHttpRequest 객체 생성
- 브라우저에게 요청을 보낼 준비
- 이것을 위해 필요한 method를 갖춘 object가 필요함
2) callback 함수
- 서버에서 응답이 왔을 때 실행시키는 함수
- HTML 페이지를 업데이트
3) Open a Request
- 서버에서 응답이 왔을 때 실행시키는 함수
- HTML 페이지를 업데이트
4) Send the Request
데이터 요청하기
//동기식 요청
function showDialog(url) {
var request = new XMLHttpRequest();
/*
true: 비동기식 요청
false: 동기식 요청
*/
request.open('GET', url, false);
request.send(null);
console.log(request.responseText);
}
//비동기식 요청
function showDialog(url) {
var request = new XMLHttpRequest();
/*
비동기식으로 요청을 하면, 언제 이 데이터가 올지 모르고, 이 데이터가 오면
그때 처리해달라는 뜻으로 콜백함수로 넘긴다. 따라서 request에 'onreadystatechange'
이벤트를 추가하여 거기서 작업을 마무리한다.
*/
request.addEventListener('readystatechange', function(e) {
if(request.readyState == 4)
console.log(request.responseText);
});
request.open('GET', 'url', [true]);
request.send(null);
}
※ onreadystatechange
- unsent : 요청을 보내기 전 (0)
- opened : 요청을 보내 데이터를 받는 통로가 열림 (1)
- headrs received : 헤더를 받았다. (2)
- loading : 데이터가 오기 시작할 때 (3)
- done : 완료 (4)
위의 방법은 조금 복잡하고 귀찮을 수 있다. 따라서 다른 이벤트가 추가가 되었는데 그것은 'onload'이다.
function showDialog(url) {
var request = new XMLHttpRequest();
request.addEventListener('load', function(e) {
console.log(request.responseText);
});
request.open('GET', 'url', [true]);
request.send(null);
}
XMLHttpRequest
- abort : 요청이 중단되었을 때
- error : 요청 중 에러가 발생했을 때
- load : 성공적으로 요청이 완료되었을 때
- loadend : 단순히 요청이 완료되었을 때
- loadstart : 데이터를 적재하기 시작했을 때 == readyState에서 (1)
- progress : 데이터를 받아올 때
loadend는 요청 중 abort / load / error를 만나도 실행이되는 것이고, load는 성공, error는 에러 때문에 중지, abort는 임의로 중지일 때 실행되는 이벤트이다. 따라서 요청이 성공하면 load를 쓰고, 실패하면 error를 쓰는 것이 바람직하다.
XMLHttpRequest를 이용해 JSON 데이터 받기
[
{"id": 61,"title": "내용없는 글","content": "null","writerId": "NEWLEC","regDate": "2021-04-30","hit": 0,"files": "null"},
{"id": 42,"title": "내용없는 글","content": "null","writerId": "newlec","regDate": "2021-04-28","hit": 0,"files": "null"},
{"id": 21,"title": "Apr","content": "냉무","writerId": "김영화","regDate": "2021-04-26","hit": 10,"files": "null"},
{"id": 20,"title": "HELLO","content": "헬로베베","writerId": "31","regDate": "2021-04-26","hit": 8,"files": "null"},
{"id": 19,"title": "asf 010-2322-2345라고요","content": "헬로베베","writerId": "31","regDate": "2021-04-26","hit": 8,"files": "null"},
{"id": 18,"title": "HIHI","content": "복습복습","writerId": "MINTING","regDate": "2021-04-26","hit": 100,"files": "null"},
{"id": 17,"title": "HI","content": "hhh","writerId": "JH","regDate": "2021-04-26","hit": 123,"files": "null"},
{"id": 16,"title": "둠칫 두둠칫","content": "혼자서 깃 치고 자바 치고","writerId": "박형준","regDate": "2021-04-26","hit": 23,"files": "null"},
{"id": 15,"title": "반갑습니다","content": "감사합니다","writerId": "hyeonOh","regDate": "2021-04-26","hit": 3,"files": "null"},
{"id": 14,"title": "WOW","content": "difficult","writerId": "yeonee","regDate": "2021-04-26","hit": 3,"files": "null"}
]
데이터베이스에서 공지사항 목록을 조회해서 JSON 형식으로 문자열을 반환했을 때의 모습이다. 위의 데이터를 반환해주는 URL 주소가 있다고 할 때, 그 주소를 localhost:8080/api/notice/list 라고 하자.
위의 주소로 데이터를 달라고 '비동기'적으로 요청을 했을 때 어떻게 오는지 보도록 한다.
Click 버튼을 누르면 데이터를 요청하는 이벤트를 달아놓았다.
btnRequest.addEventListener('click', function(e) {
var request = new XMLHttpRequest();
request.addEventListener('load', function(e) {
console.log(request.responseText);
});
/* true: 비동기, false: 동기 */
request.open('GET', 'http://localhost:8080/api/notice/list', true);
request.send(null);
});
XMLHttpRequest객체의 'load' 이벤트는 요청한 데이터가 다 받아지면 발생하는 Event 이다.
버튼을 누르면 개발자 도구 콘솔에 위와 같이 데이터가 문자열로 오는 것을 확인할 수 있다.
형식은 JSON이 맞지만, 아직 단순 문자열이다. 이를 JSON.parse를 이용해 JSON Array 형태로 변환해 한줄 한줄 객체로 찍어보자.
btnRequest.addEventListener('click', function(e) {
var request = new XMLHttpRequest();
request.addEventListener('load', function(e) {
console.log(request.responseText);
var notices = JSON.parse(request.responseText);
notices.forEach((notice, idx) => {
console.log(notice);
});
});
/* true: 비동기, false: 동기 */
request.open('GET', 'http://localhost:8080/JSPPrj/api/notice/list', true);
request.send(null);
});
이제 다시 버튼을 클릭하면.
위처럼 객체로 콘솔에 찍어준다.
# References
Newlec 선생님의 강의
'Languages > JS' 카테고리의 다른 글
[Javascript] Image 미리보기 (0) | 2021.05.27 |
---|---|
[Javascript] Ajax 모듈 (0) | 2021.05.06 |
[Javascript] Drag & Drop 파일 업로드 (0) | 2021.04.27 |
[Javascript] 이벤트 기반의 윈도우 프로그래밍 (0) | 2021.04.14 |
[JQuery] checkbox (0) | 2021.02.23 |