본문 바로가기
웹 프로그래밍

XMLHttpRequest 객체와 Ajax

by CHML 2016. 4. 9.
1. Ajax

Ajax(Asynchronous JavaScript and XML, 에이젝스)는 이용자 반응형 웹 어플리케이션 제작을 위해 HTML, DOM, JavaScript, XMLHttpRequest 등으로 구성된 웹 개발 기법이다. 기존의 웹 어플리케이션은 웹 페이지가 로드될 때 웹 서버에 요청을 전달하고, 웹 서버는 요청된 내용에 따라 데이터를 가공하여 클라이언트에게 전달하는 방식으로 동작했다. 그러나 이러한 방식의 데이터 전송은 HTML 코드를 다시 한번 더 전송해야하기 때문에 대역폭 낭비가 발생하게 된다. 또한 서버로부터 데이터를 가져올 때마다 새로고침(F5)를 누른 것처럼 페이지가 다시 로드되어야 하기 때문에 이용자 반응형 어플리케이션을 구현하기도 어렵다.

반면에 Ajax 방식을 이용한 웹 어플리케이션에서는 필요한 데이터만 서버에 요청하고 클라이언트에서 데이터를 가공할 수 있기 때문에 데이터 전송 시간과 서버 부하가 크게 감소한다. 또한 폼이 아닌 자바스크립트를 이용하여 데이터를 요청을 전송하기 때문에 클라이언트는 데이터를 수신할 때 페이지를 다시 로드할 필요가 없다.


2. XMLHttpRequest과 Same-Origin Policy

웹 브라우저 스크립트 언어에서 비동기적 통신을 위해 이용가능한 API이다. XMLHttpRequest는 웹 서버에 HTTP 또는 HTTPS 방식으로 요청을 전송하고, 결과를 수신한다. 또한 데이터를 수신할 때 현재 웹 페이지를 다시 로드하지 않고 데이터를 클라이언트 측에 전달할 수 있기 때문에 이용자 반응형 웹 어플리케이션을 개발하기에 용이하다.

XMLHttpRequest를 이용할 때는 동일 출처 정책을 지켜야한다. 동일 출처 정책이라는 것은 현재 페이지에서 다른 페이지를 접근할 때는 항상 두 페이지의 출처가 같아야한다는 것으로써, 출처가 같다는 것은 프로토콜, 호스트명, 포트가 같다는 것을 의미한다.



Chrome에서는 동일 출처 정책을 위반하는 코드를 발견하면 No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '[current domain]' is therefore not allowed access.와 같은 에러 메시지가 콘솔창에 출력된다.


3. 동기적 통신과 비동기적 통신

동기적(Synchronous) 통신은 어떤 작업을 요청했을 때 그 작업이 완료되어 응답이 올 때까지 실행 흐름을 중단하는 방식이다. 반면에 비동기적(Asynchronous) 통신은 어떤 작업에 대한 요청을 전달하고 다른 작업을 하고 있다가 요청했던 작업이 완료되었다는 응답이 오면 완료된 작업에 대한 처리를 수행하는 방식으로써 인터럽트(Interrupt)의 개념과 유사하다.


4. XMLHttpRequest 사용 예제

1) GET 방식

XMLHttpRequest를 이용하여 클라이언트(자바스크립트)와 서버(php)간의 데이터 전송에 대한 예제이다. 아래의 코드는 GET 방식을 이용하여 클라이언트와 서버간의 데이터를 전송하는 코드이다. 

request.open 메소드에서는 전달 방식과 요청 URL을 설정할 수 있으며, 3번째 인자는 동기식, 비동기식을 설정하는 부분이다. 위의 예제에서는 3번째 인자를 true로 전달하였기 때문에 비동기식으로 동작한다. 또한 request.open 메소드에서 GET 방식으로 설정하였으므로 요청 URL에 매개변수를 입력하여 전달한다. 위의 코드는 서버에서 실행되는 target.php에 p1이라는 이름의 매개변수, p2라는 이름의 매개변수를 전달한다. 각각의 매개변수의 값은 1과 432이다.

request.onreadystatechange라는 이벤트 핸들러를 등록하여 서버로부터 응답이 오면 이벤트 핸들러가 동작하도록 한다. 위의 예제에서는 응답이 오면 콘솔창에 응답 결과를 출력하도록 구현되어있다. XMLHttpRequest에 대한 모든 설정이 끝나면 코드 가장 아래에 있는 request.send(null)을 실행한다. GET 방식이므로 URL을 통해 매개변수를 전달하기 때문에 send 함수의 인자는 null이다.


2) POST 방식

GET 방식과 다르게 POST 방식에서는 XMLHttpRequest의 헤더를 반드시 설정해주어야 하며, 요청 URL을 통해 매개변수를 전달하는 것이 아니라 request.send 메소드의 인자값으로 매개변수를 전달한다. 아래의 코드는 POST 방식을 이용하여 통신하는 예제이다.

매개변수를 설정하는 두 번째 줄 코드에서 GET 방식과 다르게 매개변수의 가장 처음에 ?가 없다. GET 방식에서는 URL과 매개변수를 ?를 기준으로 구분하지만 POST 방식에서는 URL에 매개변수를 전달하지 않으므로 매개변수에 ?문자를 삽입할 필요가 없다. 또한 POST 방식에서는 반드시 헤더를 설정해야하는데 위의 예제에서는 HTML 폼 형태로 요청을 전송하기 위해 request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")라는 코드를 추가하였다. XMLHttpRequest의 헤더 타입은 여러 종류가 있으며, XMLHttpRequest의 헤더에 대한 자세한 내용은 이 문서에 서술되어 있다.