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

Ajax

by Backchus 2019. 8. 5.

1. Ajax(Asynchronous JavaScript and XML)란?

말 그대로 비동기적인 자바스크립트와 XML을 말하는 것입니다.

서버로부터 웹페이지가 반환되면 화면 전체를 갱신해야 하는데 페이지 일부만을 갱신하고도 동일한 효과를 볼 수 있도록 하는 것이 Ajax입니다. 우리가 흔히 접하는 포털사이트에서 어떤 한 목록을 클릭했을 때 화면 일부분만 바뀌는것이 바로 Ajax를 이용한 기술입니다. 페이지 전체를 로드하여 렌더링할 필요가 없고 갱신이 필요한 일부만 로드하여 갱신하기때문에 빠른 퍼포먼스와 부드러운 화면 표시효과를 기대할 수 있습니다.

 

일반적인 GET요청

 

Ajax 요청

2. JSON(JavaScript Object Notation)

클라이언트가 서버에게 요청을 보내면 서버에서 당연히 클라이언트가 요구하는 데이터를 반환해야합니다. JSON은 클라이언트와 서버 간 데이터 교환을 위한 규칙 즉 데이터 포맷을 말합니다.

JSON은 일반 텍스트 포맷보다 효과적인 데이터 구조화가 가능하며 XML 포맷보다 가볍고 사용하기 간편하며 가독성이 좋다는 장점이 있습니다. 

1
2
3
4
5
6
{
  "name""Lee",
  "gender""male",
  "age"20,
  "alive"true
}
 

자바스크립트의 객체 리터럴과 매우 흡사해 보이지만 JSON은 순수한 텍스트로 구성된 규칙이 있는 데이터 구조입니다.

다음은 JSON을 이용하기 위한 메소드를 알아보겠습니다.

2.1 JSON.stringify

JSON.stringify 메소드는 객체를 JSON 형식의 문자열로 변환합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const o = { name'Lee', gender: 'male', age: 20 };
 
// 객체 => JSON 형식의 문자열
const strObject = JSON.stringify(o);
console.log(typeof strObject, strObject);
// string {"name":"Lee","gender":"male","age":20}
 
// 객체 => JSON 형식의 문자열 + prettify
const strPrettyObject = JSON.stringify(o, null2);
console.log(typeof strPrettyObject, strPrettyObject);
/*
string {
  "name": "Lee",
  "gender": "male",
  "age": 20
}
*/
 

객체리터럴 o를 stringify를 이용해서 JSON형식의 문자데이터로 변환하였습니다.

9번 라인에서 사용한 stringify의 매개변수를 좀더 알아보겠습니다.

첫번째 인자는 JSON 문자열로 변환할 값입니다.

두번째 인자는 문자열의 동작 방식을 변경하는 함수로 null이거나 제공되지 않으면, 객체의 모든 속성들이 JSON 문자열 결과에 포함됩니다.

세번째 인자는 가독성을 목적으로 JSON 문자열 출력에 공백을 삽입하는데 사용되는 타입은 String 또는 Number 타입 입니다. Number타입이라면, 공백으로 사용되는 스페이스(space)의 수를 나타냅니다. String타입이라면, 그 문자열이 공백으로 사용됩니다. 매개변수가 제공되지 않는다면, 공백이 사용되지 않습니다.

2.2 JSON.parse

JSON.parse 메소드는 JSON 데이터를 가진 문자열을 객체로 변환합니다.

서버로부터 브라우저로 전송된 JSON 데이터는 문자열입니다. 이 문자열을 객체로서 사용하려면 객체화하여야 하는데 이를 역직렬화(Deserializing)이라 합니다. 역직렬화를 위해서 내장 객체 JSON의 static 메소드인 JSON.parse를 사용합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const o = { name'Lee', gender: 'male', age: 20 };
 
// 객체 => JSON 형식의 문자열
const strObject = JSON.stringify(o);
console.log(typeof strObject, strObject);
// string {"name":"Lee","gender":"male","age":20}
 
const arr = [15'false'];
 
// 배열 객체 => 문자열
const strArray = JSON.stringify(arr);
console.log(typeof strArray, strArray); // string [1,5,"false"]
 
// JSON 형식의 문자열 => 객체
const obj = JSON.parse(strObject);
console.log(typeof obj, obj); // object { name: 'Lee', gender: 'male' }
 
// 문자열 => 배열 객체
const objArray = JSON.parse(strArray);
console.log(typeof objArray, objArray); // object [1, 5, "false"]
 

배열이 JSON 형식의 문자열로 반환되어 있는 경우 JSON.parse는 문자열을 배열 객체로 반환합니다. 배열의 요소가 객체인 경우 배열의 요소까지 객체로 변환합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
const todos = [
  { id: 1content'HTML', completed: true },
  { id: 2content'CSS', completed: true },
  { id: 3content'JavaScript', completed: false }
];
 
// 배열 => JSON 형식의 문자열
const str = JSON.stringify(todos);
console.log(typeof str, str);
 
// JSON 형식의 문자열 => 배열
const parsed = JSON.parse(str);
console.log(typeof parsed, parsed);
 

3. XMLHttpRequest

브라우저는 XMLHttpRequest 객체를 이용하여 Ajax 요청을 생성하고 전송합니다. 서버가 브라우저의 요청에 대해 응답을 반환하면 같은 XMLHttpRequest 객체가 그 결과를 처리합니다.

3.1 Ajax request

Ajax 요청 처리의 예입니다.

1
2
3
4
5
6
// XMLHttpRequest 객체의 생성
const xhr = new XMLHttpRequest();
// 비동기 방식으로 Request를 오픈한다
xhr.open('GET''/users');
// Request를 전송한다
 

3.1.1 XMLHttpRequest.open

XMLHttpRequest 객체의 인스턴스를 생성하고 XMLHttpRequest.open 메소드를 사용하여 서버로의 요청을 준비합니다.

1
 

 

매개변수 설명
method Http method("GET", "POST", "PUT", "DELETE" 등)
url 요청을 보낼 URL
async 비동기 조작 여부, 옵션으로 default는 true이며 비동기 방식으로 동작 한다.

3.1.2 XMLHttpRequest.send

XMLHttpRequest.send 메소드로 준비된 요청을 서버에 전달합니다.

기본적으로 서버로 전송하는 데이터는 GET, POST 메소드에 따라 그 전송 방식에 차이가 있습니다.

  • GET 메소드의 경우, URL의 일부분인 쿼리문자열(query, string)로 데이터를 서버로 전송합니다.
  • POST 메소드의 경우, 데이터(페이로드)를 Request Body에 담아 전송합니다
HTTP 요청/응답 메세지 예

XMLHttpRequest.send 메소드에는 request body에 담아 전송할 인수를 전달할 수 있습니다.

1
2
3
4
5
 
 

만약 요청 메소드가 GET인 경우, send 메소드의 인수는 무시되고 request body는 null로 설정됩니다.

3.1.3 XMLHttpRequest.setRequestHeader

XMLHttpRequest.setRequestHeader 메소드는 HTTP Request Header의 값을 설정합니다. setRequestHeader 메소드는 반드시 XMLHttpRequest.open 메소드 호출 이후에 호출합니다.

자주 사용하는 Request Header인 Content-type, Accept에 대해 살펴보겠습니다.

content-type

content-type은 request body에 담아 전송할 데이터의 MIME-type의 정보를 표현합니다. 자주 사용되는 MIME-type은 아래와 같습니다.

타입 서브타입
text 타입 text/plain, text/html, text/css, text/javascript
Application 타입 application/json, application/x-www-form-urlencode
File을 업로드하기 위한 타입 multipart/formed-data

다음은 request body에 담아 서버로 전송할 데이터의 MIME-type을 지정하는 예입니다.

1
2
3
4
5
6
7
8
9
// json으로 전송하는 경우
xhr.open('POST''/users');
 
// 클라이언트가 서버로 전송할 데이터의 MIME-type 지정: json
xhr.setRequestHeader('Content-type''application/json');
 
const data = { id: 3, title: 'JavaScript', author: 'Park', price: 5000};
 
 

Accept

HTTP 클라이언트가 서버에 요청할 때 서버가 센드백할 데이터의 MIME-type을 Accept로 지정할 수 있습니다.

1
2
// 서버가 센드백할 데이터의 MIME-type 지정: json
xhr.setRequestHeader('Accept''application/json');
 

만약 Accept 헤더를 설정하지 않으면, send 메소드가 호출될 때 Accept 헤더가 */*으로 전송됩니다.

3.2 Ajax response

다음은 Ajax 응답 처리의 예입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// XMLHttpRequest 객체의 생성
const xhr = new XMLHttpRequest();
 
// XMLHttpRequest.readyState 프로퍼티가 변경(이벤트 발생)될 때마다 onreadystatechange 이벤트 핸들러가 호출된다.
xhr.onreadystatechange = function (e) {
  // readyStates는 XMLHttpRequest의 상태(state)를 반환
  // readyState: 4 => DONE(서버 응답 완료)
  if (xhr.readyState !== XMLHttpRequest.DONE) return;
 
  // status는 response 상태 코드를 반환 : 200 => 정상 응답
  if(xhr.status === 200) {
    console.log(xhr.responseText);
  } else {
    console.log('Error!');
  }
};
 
 

위 코드를 좀 더 자세히 살펴보겠습니다.

XMLHttpRequest.send 메소드를 통해 서버에 Request를 전송하면 서버는 Response를 반환합니다. 하지만 언제 Response가 클라이언트에 도달할 지는 알 수 없습니다. XMLHttpRequest.onreadystatechange는 Response가 클라이언트가 도달하여 발생된 이벤트를 감지하고 콜백 함수를 실행하여 줍니다. 이때 이벤트는 Requset에 어떠한 변화가 발생한 경우 즉 XMLHttpRequest.readyState 프로퍼티가 변경된 경우 발생합니다.

1
2
3
4
5
6
7
8
9
10
11
// XMLHttpRequest 객체의 생성
var xhr = new XMLHttpRequest();
// 비동기 방식으로 Request를 오픈한다
xhr.open('GET''data/test.json');
// Request를 전송한다
 
// XMLHttpRequest.readyState 프로퍼티가 변경(이벤트 발생)될 때마다 콜백함수(이벤트 핸들러)를 호출한다.
xhr.onreadystatechange = function (e) {
  // 이 함수는 Response가 클라이언트에 도달하면 호출된다.
 
 

XMLHttpRequest 객체는 response가 클라이언트에 도달했는지를 추적할 수 있는 프로퍼티를 제공합니다. 이 프로퍼티가 바로 XMLHttpRequest.readyState이다. 만일 XMLHttpRequest.readyState의 값이 4인 경우, 정상적으로 Response가 돌아온 경우입니다.

readXMLHttpRequest.readyState의 값은 아래와 같습니다.

Value State Description
0 UNSENT XMLHttpRequest.open() 메소드 호출 이전
1 OPENED XMLHttpRequest.open() 메소드 호출 완료
2 HEADERS_RECEIVED XMLHttpRequest.send() 메소드 호출 완료
3 LOADING 서버 응답 중(XMLHttpRequest.responseText 미완성 상태)
4 DONE 서버 응답 완료
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// XMLHttpRequest 객체의 생성
var xhr = new XMLHttpRequest();
// 비동기 방식으로 Request를 오픈한다
xhr.open('GET''data/test.json');
// Request를 전송한다
 
// XMLHttpRequest.readyState 프로퍼티가 변경(이벤트 발생)될 때마다 콜백함수(이벤트 핸들러)를 호출한다.
xhr.onreadystatechange = function (e) {
  // 이 함수는 Response가 클라이언트에 도달하면 호출된다.
 
  // readyStates는 XMLHttpRequest의 상태(state)를 반환
  // readyState: 4 => DONE(서버 응답 완료)
  if (xhr.readyState !== XMLHttpRequest.DONE) return;
 
  // status는 response 상태 코드를 반환 : 200 => 정상 응답
  if(xhr.status === 200) {
    console.log(xhr.responseText);
  } else {
    console.log('Error!');
  }
};
 
 

XMLHttpRequest의 readyState가 4인 경우, 서버 응답이 완료된 상태이므로 이후 XMLHttpRequest.status가 200(정상 응답)임을 확인하고 정상인 경우, XMLHttpRequest.responseText를 취득한다. XMLHttpRequest.responseText에는 서버가 전송한 데이터가 담겨 있다.

 

참고자료: https://poiemaweb.com/js-ajax

 

Ajax | PoiemaWeb

비동기식 처리 모델(Asynchronous processing model or Non-Blocking processing model)은 병렬적으로 작업을 수행한다. 즉, 작업이 종료되지 않은 상태라도 대기하지 않고 다음 작업을 실행한다는 의미이다. 예를 들어 서버에서 데이터를 가져와 화면에 표시하는 작업을 수행할 경우 서버에 데이터를 요청한 이후 서버로부터 데이터가 전달될 때까지 대기하지 않고(Non-Blocking) 즉시 다음 작업을 수행한다. 이후 서

poiemaweb.com

참고자료: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

 

JSON.stringify()

JSON.stringify() 메서드는 JavaScript 값이나 객체를 JSON 문자열로 변환합니다.

developer.mozilla.org

 

'웹 프로그래밍' 카테고리의 다른 글

WAS(Web Application Server)  (0) 2019.01.23
웹서버  (0) 2019.01.23
browser의 동작  (0) 2019.01.23