43장 Ajax
43.1 Ajax란?
-
Ajax란 자바스크립트를 사용하여 브라우저가 서버에게 비동기 방식으로 데이터를 요청하고, 서버가 응답한 데이터를 수신하여 웹페이지를 동적으로 갱신하는 프로그래밍 방식을 의미
-
브라우저에서 제공하는 Web API인 XMLHttpRequest 객체 기반으로 동작. HTTP 비동기 통신을 위한 메소드, 프로퍼티를 제공
-
장점이 불필요한 렌더링이 필요없이 필요한 부분만 렌더링 한다는 점과 블로킹이 없다는점(비동기니까)
43.2 JSON
- JSON은 클라이언트와 서버 간의 HTTP 통신을 위한 텍스트 데이터 포맷 독립형 데이터 포맷으로, 대부분의 프로그래밍 언어에서 사용 가능
43.2.1 JSON 표기 방식(43-01)
-
키와 값으로 구성
-
키는 꼭 큰따옴표를 사용해야함
{
"name": "Lee",
"age": 20,
"alive": true,
"hobby": ["traveling", "tennis"]
}
43.2.2 JSON.stringify(43-02)
-
JSON.stringify 메서드는 객체를 JSON 포맷의 문자열로 변환
-
사용법은 예제를 확인
const obj = {
name: 'Lee',
age: 20,
alive: true,
hobby: ['traveling', 'tennis']
};
// 객체를 JSON 포맷의 문자열로 변환한다.
const json = JSON.stringify(obj);
console.log(typeof json, json);
// string {"name":"Lee","age":20,"alive":true,"hobby":["traveling","tennis"]}
// 객체를 JSON 포맷의 문자열로 변환하면서 들여쓰기 한다.
const prettyJson = JSON.stringify(obj, null, 2);
console.log(typeof prettyJson, prettyJson);
/*
string {
"name": "Lee",
"age": 20,
"alive": true,
"hobby": [
"traveling",
"tennis"
]
}
*/
// replacer 함수. 값의 타입이 Number이면 필터링되어 반환되지 않는다.
function filter(key, value) {
// undefined: 반환하지 않음
return typeof value === 'number' ? undefined : value;
}
// JSON.stringify 메서드에 두 번째 인수로 replacer 함수를 전달한다.
const strFilteredObject = JSON.stringify(obj, filter, 2);
console.log(typeof strFilteredObject, strFilteredObject);
/*
string {
"name": "Lee",
"alive": true,
"hobby": [
"traveling",
"tennis"
]
}
*/
43-03
- 배열도 JSON으로 변환 가능
const todos = [
{ id: 1, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 3, content: 'Javascript', completed: false }
];
// 배열을 JSON 포맷의 문자열로 변환한다.
const json = JSON.stringify(todos, null, 2);
console.log(typeof json, json);
/*
string [
{
"id": 1,
"content": "HTML",
"completed": false
},
{
"id": 2,
"content": "CSS",
"completed": true
},
{
"id": 3,
"content": "Javascript",
"completed": false
}
]
*/
43.2.3 JSON.parse(43-04)
- JSON.parse 메서드는 JSON 포맷의 문자열을 객체로 변환
const obj = {
name: 'Lee',
age: 20,
alive: true,
hobby: ['traveling', 'tennis']
};
// 객체를 JSON 포맷의 문자열로 변환한다.
const json = JSON.stringify(obj);
// JSON 포맷의 문자열을 객체로 변환한다.
const parsed = JSON.parse(json);
console.log(typeof parsed, parsed);
// object {name: "Lee", age: 20, alive: true, hobby: ["traveling", "tennis"]}
43-05
- 배열이 JSON 포맷의 문자열로 변환되어 있는 경우 배열로 반환 다시해줌
const todos = [
{ id: 1, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 3, content: 'Javascript', completed: false }
];
// 배열을 JSON 포맷의 문자열로 변환한다.
const json = JSON.stringify(todos);
// JSON 포맷의 문자열을 배열로 변환한다. 배열의 요소까지 객체로 변환된다.
const parsed = JSON.parse(json);
console.log(typeof parsed, parsed);
/*
object [
{ id: 1, content: 'HTML', completed: false },
{ id: 2, content: 'CSS', completed: true },
{ id: 3, content: 'Javascript', completed: false }
]
*/
43.3 XMLHttpRequest
- 브라우저에서 주소창, form, a태그 등으로 HTTP 요청 전송 기능을 기본 제공. 자바스크립트는 ? Web API인 XMLHttpRequest 객체 사용
43.3.1 XMLHttpRequest 객체 생성(43-06)
- 당연히 Web API이므로 브라우저 환경에서만 정상 실행
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
43.3.2 XMLHttpRequest 객체의 프로퍼티와 메서드
중요한 것들은 볼드체로 표시
- 1.XMLHttpRequest 객체의 프로토타입 프로퍼티
- readyState : HTTP 요청의 현재 상태를 나타내는 정수(예 : 정적 프로퍼티. 0,1,2,3,4) status : HTTP 요청에 대한 응답 상태 나타내는 정수(예 : 200) statusText : HTTP 요청에 대한 응답 메시지를 나타내는 문자열(예 : “OK”) responseType : HTTP 응답 타입(예 : document, json, text, blob, arraybuffer) response : HTTP 요청에 대한 응답 몸체. responseType에 따라 타입이 다름 responseText : 서버가 전송한 HTTP 요청에 대한 응답 문자열
- 2.XMLHttpRequest 객체의 이벤트 핸들러 프로퍼티
- onreadystatechange : readyState 프로퍼티 값이 변경된 경우 onloadstart : HTTP 요청에 대한 응답을 받기 시작한 경우 onprogress : HTTP 요청에 대한 응답을 받는 도중 주기적으로 발생 onabort : abort 메서드에 의해 HTTP 요청이 중단된 경우 onerror : HTTP 요청에 에러가 발생한 경우 onload : HTTP 요청이 성공적으로 완료한 경우 ontimeout : HTTP 요청 시간이 초과한 경우 onloadend : HTTP 요청이 완료한 경우. HTTP 요청이 성공 또는 실패하면 발생
- 3.XMLHttpRequest 객체의 메서드
- open : HTTP 요청 초기화 send : HTTP 요청 전송 abort : 이미 전송된 HTTP 요청 중단 setRequestHeader : 특정 HTTP 요청 헤더의 값을 설정 getResponseHeader : 특정 HTTP 요청 헤더의 값을 문자열로 반환
- 4.XMLHttpRequest 객체의 정적 프로퍼티
- UNSENT : open 메서드 호출 이전(0) OPENED : open 메서드 호출 이후(1) HEADERS_RECEIVED : send 메서드 호출 이후(2) LOADING : 서버 응답 중(3) DONE : 서버 응답 완료(4)
43.3.3 HTTP 요청 전송(43-07)
-
다음 순서를 따름
-
open의 인수 3개 method : GET, POST, PUT, DELETE 등 url : HTTP 요청을 전송할 URL async : 비동기 요청 여부. 기본값 true(비동기)
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// 1. HTTP 요청 초기화
xhr.open('GET', '/users');
// 2. HTTP 요청 헤더 설정
// 클라이언트가 서버로 전송할 데이터의 MIME 타입 지정: json
xhr.setRequestHeader('content-type', 'application/json');
// 3. HTTP 요청 전송
xhr.send();
43-08
-
send에서 요청 몸체에 담아 전송할 데이터(페이로드)가 객체인 경우 직렬화 해주기
-
HTTP 요청 메서드가 GET인 경우 send 메서드에 페이로드로 전달한 인수는 무시되고 요청 몸체는 null로 설정. 왜냐?
-
GET 요청 메서드는 데이터를 URL의 일부분인 쿼리 문자열로 서버에 전송 POST 요청 메서드는 데이터(페이로드)를 요청 몸체에 담아 전송
xhr.send(JSON.stringify({ id: 1, content: 'HTML', completed: false }));
43-09
-
setRequestHeader 메서드는 open 메서드 호출 이후에 꼭 호출 주 사용 HTTP 요청 헤더는 Content-type, Accept
-
Content-type은 MIME 타입의 정보를 표현. 주 사용 MIME 타입은? text : text/javascript, text/css 등등 application : application/json, 등등 multipart : multipart/formed-data
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
xhr.open('POST', '/users');
// HTTP 요청 헤더 설정
// 클라이언트가 서버로 전송할 데이터의 MIME 타입 지정: json
xhr.setRequestHeader('content-type', 'application/json');
// HTTP 요청 전송
xhr.send(JSON.stringify({ id: 1, content: 'HTML', completed: false }));
43-10
- 서버가 응답할 데이터의 MIME 타입은 Accept로 지정 가능
// 서버가 응답할 데이터의 MIME 타입 지정: json
xhr.setRequestHeader('accept', 'application/json');
43.3.4 HTTP 응답 처리(43-11)
-
readystatechange 이벤트는 HTTP 요청의 현재 상태를 나타내는 readyState 프로퍼티가 변경될 때마다 발생. 이를 활용
-
참고로 HTTP 요청을 전송하고 응답을 받으려먼 서버가 필요. 아래 예제는 가상 REST API사용
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// https://jsonplaceholder.typicode.com은 Fake REST API를 제공하는 서비스다.
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
// HTTP 요청 전송
xhr.send();
// readystatechange 이벤트는 HTTP 요청의 현재 상태를 나타내는 readyState 프로퍼티가
// 변경될 때마다 발생한다.
xhr.onreadystatechange = () => {
// readyState 프로퍼티는 HTTP 요청의 현재 상태를 나타낸다.
// readyState 프로퍼티 값이 4(XMLHttpRequest.DONE)가 아니면 서버 응답이 완료되지 상태다.
// 만약 서버 응답이 아직 완료되지 않았다면 아무런 처리를 하지 않는다.
if (xhr.readyState !== XMLHttpRequest.DONE) return;
// status 프로퍼티는 응답 상태 코드를 나타낸다.
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태이고
// status 프로퍼티 값이 200이 아니면 에러가 발생한 상태다.
// 정상적으로 응답된 상태라면 response 프로퍼티에 서버의 응답 결과가 담겨 있다.
if (xhr.status === 200) {
console.log(JSON.parse(xhr.response));
// {userId: 1, id: 1, title: "delectus aut autem", completed: false}
} else {
console.error('Error', xhr.status, xhr.statusText);
}
};
- load 이벤트를 캐치해도 좋다. 애초에 load 이벤트는 HTTP 요청이 성공적으로 완료된 경우 발생하기 때문
43-12
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// https://jsonplaceholder.typicode.com은 Fake REST API를 제공하는 서비스다.
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
// HTTP 요청 전송
xhr.send();
// load 이벤트는 HTTP 요청이 성공적으로 완료된 경우 발생한다.
xhr.onload = () => {
// status 프로퍼티는 응답 상태 코드를 나타낸다.
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태이고
// status 프로퍼티 값이 200이 아니면 에러가 발생한 상태다.
// 정상적으로 응답된 상태라면 response 프로퍼티에 서버의 응답 결과가 담겨 있다.
if (xhr.status === 200) {
console.log(JSON.parse(xhr.response));
// {userId: 1, id: 1, title: "delectus aut autem", completed: false}
} else {
console.error('Error', xhr.status, xhr.statusText);
}
};
댓글남기기